Skip to content

Commit

Permalink
Better handling of circular references
Browse files Browse the repository at this point in the history
  • Loading branch information
zalmoxisus committed Oct 15, 2016
1 parent af55fa1 commit 61ceb47
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 44 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
"redux": "^3.5.2",
"redux-devtools": "^3.3.1",
"redux-devtools-instrument": "^1.3.2",
"remotedev-app": "^0.8.0-beta-8",
"remotedev-app": "^0.8.0-beta-12",
"remotedev-slider": "^1.0.1",
"remotedev-utils": "0.0.1"
}
Expand Down
42 changes: 11 additions & 31 deletions src/app/api/index.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,28 @@
import jsan from 'jsan';
import { stringify } from 'jsan';

const listeners = {};
export const source = '@devtools-page';
let isCircular;

export default function stringify(obj, replacer, type) {
if (type === 2) { // Deep serialization
return jsan.stringify(obj, function(key, value) {
if (value && value.toJS) { return value.toJS(); }
return value;
}, null, true);
}
return jsan.stringify(obj, replacer);
}

export function generateId(instanceId) {
return instanceId || Math.random().toString(36).substr(2);
}

function tryCatch(fn, args) {
try {
return fn(args);
} catch (err) {
isCircular = true;
toContentScript(args);
}
}

function post(message) {
window.postMessage(message, '*');
}

export function toContentScript(message, shouldStringify, serializeState, serializeAction) {
if (shouldStringify || isCircular) {
if (message.type !== 'ERROR' && message.type !== 'GET_REPORT' && message.payload) {
message.payload = stringify(message.payload, serializeState);
}
if (message.type !== 'STATE' && message.action) {
message.action = stringify(message.action, serializeAction);
}
post(message);
} else {
tryCatch(post, message);
if (message.type === 'ACTION') {
message.action = stringify(message.action, serializeAction);
message.payload = stringify(message.payload, serializeState);
} else if (message.type === 'STATE') {
const { actionsById, computedStates, committedState, ...rest } = message.payload;
message.payload = rest;
message.actionsById = stringify(actionsById, serializeAction);
message.computedStates = stringify(computedStates, serializeState);
message.committedState = stringify(committedState, serializeState);
}
post(message);
}

export function sendMessage(action, state, shouldStringify, id, name) {
Expand Down
9 changes: 6 additions & 3 deletions test/app/inject/api.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe('API', () => {
});
expect(message).toInclude({
type: 'ACTION',
action: { action: { type: 'hi' } },
action: '{"action":{"type":"hi"}}',
payload: undefined,
id: undefined,
name: '',
Expand All @@ -45,8 +45,8 @@ describe('API', () => {
});
expect(message).toInclude({
type: 'ACTION',
action: { action: { type: 'hi' } },
payload: { counter: 1 },
action: '{"action":{"type":"hi"}}',
payload: '{"counter":1}',
instanceId: 1,
name: '',
source: '@devtools-page'
Expand All @@ -70,6 +70,9 @@ describe('API', () => {
expect(message).toEqual({
type: 'STATE',
payload: { counter: 1 },
actionsById: undefined,
computedStates: undefined,
committedState: undefined,
instanceId: 1,
name: '',
source: '@devtools-page'
Expand Down
17 changes: 8 additions & 9 deletions test/app/inject/enhancer.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ describe('Redux enhancer', () => {

message = await listenMessage();
expect(message.type).toBe('STATE');
expect(message.payload.actionsById[0].action.type).toBe('@@INIT');
expect(message.payload.computedStates[0].state).toBe(0);
expect(message.actionsById).toInclude('{"0":{"type":"PERFORM_ACTION","action":{"type":"@@INIT"},"');
expect(message.computedStates).toBe('[{"state":0}]');
});

it('should perform actions', async () => {
Expand All @@ -41,16 +41,16 @@ describe('Redux enhancer', () => {
expect(window.store.getState()).toBe(1);
});
expect(message.type).toBe('ACTION');
expect(message.action.action.type).toBe('INCREMENT');
expect(message.payload).toBe(1);
expect(message.action).toInclude('{"type":"PERFORM_ACTION","action":{"type":"INCREMENT"},');
expect(message.payload).toBe('1');

message = await listenMessage(() => {
window.store.dispatch({ type: 'INCREMENT' });
expect(window.store.getState()).toBe(2);
});
expect(message.type).toBe('ACTION');
expect(message.action.action.type).toBe('INCREMENT');
expect(message.payload).toBe(2);
expect(message.action).toInclude('{"type":"PERFORM_ACTION","action":{"type":"INCREMENT"},');
expect(message.payload).toBe('2');
});

it('should dispatch actions remotely', async () => {
Expand All @@ -65,8 +65,8 @@ describe('Redux enhancer', () => {

message = await listenMessage();
expect(message.type).toBe('ACTION');
expect(message.action.action.type).toBe('INCREMENT');
expect(message.payload).toBe(3);
expect(message.action).toInclude('{"type":"PERFORM_ACTION","action":{"type":"INCREMENT"},');
expect(message.payload).toBe('3');
});

it('should cancel (toggle) action', async () => {
Expand All @@ -81,7 +81,6 @@ describe('Redux enhancer', () => {

message = await listenMessage();
expect(message.type).toBe('STATE');
expect(message.payload.computedStates[message.payload.computedStates.length - 1].state).toBe(2);
expect(window.store.getState()).toBe(2);

message = await listenMessage(() => {
Expand Down

0 comments on commit 61ceb47

Please sign in to comment.