Skip to content

Commit

Permalink
ReduxActionMonitor middleware done
Browse files Browse the repository at this point in the history
  • Loading branch information
RNEvok committed Jun 18, 2023
1 parent bb035f1 commit 3cdb977
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 7 deletions.
28 changes: 25 additions & 3 deletions Connector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,23 @@ import {
NetworkInterceptorInstance,
NetworkInterceptorOnRequestPayload,
NetworkInterceptorOnResponsePayload,
AdminConnectedData
AdminConnectedData,
InterceptedReduxAction
} from './types';
import { CONFIG } from './config';
import { EventHandleError, ScenarioHandleError } from './Errors';
import { api, SOCKET_EVENTS_LISTEN, SOCKET_EVENTS_EMIT } from './api/api';
import { SPECIAL_INSTRUCTIONS_TABLE, SPECIAL_INSTRUCTIONS } from './constants/events';
import { io, Socket } from "socket.io-client";
import { codebudConsoleLog, codebudConsoleWarn, stringifyIfNotString } from './helperFunctions';
import { codebudConsoleLog, codebudConsoleWarn, jsonStringifyKeepMethods, stringifyIfNotString } from './helperFunctions';
import moment from 'moment';

export class Connector {
private static _currentInstanceId = 0;
private static _remoteSettings: RemoteSettings | null = null;
private static _eventListenersTable: EventListenersTable = {};
private static _remoteSettingsListenersTable: RemoteSettingsListenersTable = {};
private static _currentInterceptedReduxActionId = 0;
private _apiKey: string;
private _instructionsTable: InstructionsTable = {};
private _onEventUsersCustomCallback: OnEventUsersCustomCallback;
Expand All @@ -41,6 +43,8 @@ export class Connector {
private _socket: Socket;
private _sendReduxStateBatchingTimer: NodeJS.Timeout | null = null;
private _currentReduxStateCopy: any = null;
private _sendReduxActionsBatchingTimer: NodeJS.Timeout | null = null;
private _currentReduxActionsBatch: any[] = [];
private _encryption: any = null;

public static lastEvent: RemoteEvent | null = null;
Expand All @@ -64,7 +68,7 @@ export class Connector {

private _encryptData(json: any) {
if (!this._encryption)
return JSON.stringify(json);
return jsonStringifyKeepMethods(json);

return this._encryption.encryptData(json);
};
Expand Down Expand Up @@ -350,6 +354,23 @@ export class Connector {
}
}

public handleDispatchedReduxAction(action: InterceptedReduxAction, batchingTimeMs: number) {
if (this._socket.connected) {
const timestamp = moment().valueOf();
const actionId = Connector._currentInterceptedReduxActionId++;
this._currentReduxActionsBatch.push({actionId: `RA_${actionId}`, action, timestamp});

if (this._sendReduxActionsBatchingTimer)
clearTimeout(this._sendReduxActionsBatchingTimer);

this._sendReduxActionsBatchingTimer = setTimeout(() => {
const encryptedData = this._encryptData({actions: this._currentReduxActionsBatch});
this._socket?.emit(SOCKET_EVENTS_EMIT.SAVE_REDUX_ACTIONS_BATCH, encryptedData);
this._currentReduxActionsBatch = [];
}, batchingTimeMs);
}
}

public static get remoteSettings(): RemoteSettings | null {
return Connector._remoteSettings;
}
Expand All @@ -363,6 +384,7 @@ export class Connector {
this._lastEventLog = undefined;
this._dataToForward = null;
this._currentReduxStateCopy = null;
this._currentReduxActionsBatch = [];
this._encryption = null;

if (this._networkInterceptor) {
Expand Down
1 change: 0 additions & 1 deletion Network/NetworkInterceptorClassic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ class NetworkInterceptorClassic extends NetworkInterceptorApi {
private _interceptor: ClientRequestInterceptor | null = null;

protected async formatRequest(request: any) {
console.log('DEBUG', Object.fromEntries(request.headers));
let body: any;
const isJsonContentType = request.headers.get("content-type")?.includes("application/json");

Expand Down
1 change: 1 addition & 0 deletions api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const SOCKET_EVENTS_EMIT = {
EXECUTING_SCENARIO: "executingScenario",
SAVE_SCENARIO_LOG: "saveScenarioLog",
SAVE_REDUX_STATE_COPY: "saveReduxStateCopy",
SAVE_REDUX_ACTIONS_BATCH: "saveReduxActionsBatch",
SAVE_INTERCEPTED_REQUEST: "saveInterceptedRequest",
SAVE_INTERCEPTED_RESPONSE: "saveInterceptedResponse",
SAVE_MOBILE_APP_STATE: "saveMobileAppState"
Expand Down
4 changes: 2 additions & 2 deletions encryption/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { box, randomBytes } from 'tweetnacl';
import { decodeUTF8, encodeBase64 } from 'tweetnacl-util';
import { codebudConsoleLog, codebudConsoleWarn } from '../helperFunctions';
import { codebudConsoleLog, codebudConsoleWarn, jsonStringifyKeepMethods } from '../helperFunctions';

export class EncryptionPlugin {
private _keyPair: nacl.BoxKeyPair | null = null;
Expand All @@ -17,7 +17,7 @@ export class EncryptionPlugin {
throw new Error("Shared key not generated");

const nonce = this.newNonce();
const messageUint8 = decodeUTF8(JSON.stringify(json));
const messageUint8 = decodeUTF8(jsonStringifyKeepMethods(json));

const encrypted = box.after(messageUint8, nonce, this._sharedKey);

Expand Down
19 changes: 19 additions & 0 deletions helperFunctions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { CONFIG } from "./config";
import { ObjectT } from "./types";

export function delay(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
Expand Down Expand Up @@ -35,4 +36,22 @@ export const codebudConsoleWarn = (...data: any[]) => {

export const codebudConsoleLog = (...data: any[]) => {
console.log(`${CONFIG.PRODUCT_NAME}:`, ...data);
}

// @ts-ignore
export const emptyMiddleware = () => next => action => {
return next(action);
}

export const jsonStringifyKeepMethods = (data: ObjectT<any>) => {
return JSON.stringify(
data,
function(key, value) {
if (typeof value === 'function') {
return "Function (...)";
} else {
return value;
}
}
);
}
6 changes: 6 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,12 @@ declare module '@appklaar/codebud' {
* @returns {Function} Store change handler function.
*/
createReduxStoreChangeHandler: (store: any, selectFn: (state: any) => any, batchingTimeMs?: number) => (() => void);
/**
* Function that creates Redux middleware for actions monitoring.
* @param {number} [batchingTimeMs = 200] batching time of sending dispatched redux actions (in ms). Defaults to 200. This param only affects logging delay and does not slow down your redux flow.
* @returns {Function} Middleware
*/
createReduxActionMonitorMiddleware: (batchingTimeMs?: number) => any;
/**
* Close the connection.
*/
Expand Down
12 changes: 11 additions & 1 deletion index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { EXISTING_SPECIAL_INSTRUCTION_IDS } from './constants/events';
import { validateApiKey } from './constants/regex';
import { AppKlaarSdk as ModuleInterface } from './moduleInterface';
import { CONFIG } from './config';
import { codebudConsoleWarn } from './helperFunctions';
import { codebudConsoleWarn, emptyMiddleware } from './helperFunctions';

export type { Instruction } from './types';

Expand Down Expand Up @@ -109,6 +109,16 @@ export const CodeBud: ModuleInterface = {
}
},

createReduxActionMonitorMiddleware(batchingTimeMs = 200) {
// @ts-ignore
return () => next => action => {
if (this._connector)
this._connector.handleDispatchedReduxAction(action, batchingTimeMs);

return next(action);
}
},

disconnect() {
this._connector && this._connector.disconnect();
this._connector = null;
Expand Down
6 changes: 6 additions & 0 deletions moduleInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ export interface AppKlaarSdk {
* @returns {Function} Store change handler function.
*/
createReduxStoreChangeHandler: (store: any, selectFn: (state: any) => any, batchingTimeMs?: number) => (() => void);
/**
* Function that creates Redux middleware for actions monitoring.
* @param {number} [batchingTimeMs = 200] batching time of sending dispatched redux actions (in ms). Defaults to 200. This param only affects logging delay and does not slow down your redux flow.
* @returns {Function} Middleware
*/
createReduxActionMonitorMiddleware: (batchingTimeMs?: number) => any;
/**
* Close the connection.
*/
Expand Down
5 changes: 5 additions & 0 deletions types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ export type InterceptedResponse = {
responseHeaders?: ObjectT<any> | undefined;
};

export type InterceptedReduxAction = {
type: string;
payload?: any;
}

export type NetworkInterceptorOnRequestPayload = {
request: InterceptedRequest;
requestId: string;
Expand Down

0 comments on commit 3cdb977

Please sign in to comment.