Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.

Commit 4853833

Browse files
committed
wip
1 parent eabc021 commit 4853833

5 files changed

Lines changed: 160 additions & 51 deletions

File tree

src/actions/breakpoints.js

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,15 @@ function _breakpointExists(state, location: Location) {
2424
return currentBp && !currentBp.disabled;
2525
}
2626

27-
function _createBreakpoint(location: Location, opts: Object = {}) {
28-
return Object.assign({}, { location }, opts);
27+
function _createBreakpoint(location: Location, reference: Object = {}) {
28+
const { condition, disabled } = reference;
29+
const properties = {
30+
condition: condition || null,
31+
disabled: disabled || false,
32+
location
33+
};
34+
35+
return properties;
2936
}
3037

3138
async function _getGeneratedLocation(source, sourceMaps, location) {
@@ -82,6 +89,43 @@ export function enableBreakpoint(location: Location) {
8289
};
8390
}
8491

92+
export function syncBreakpoint(location, referenceBreakpoint) {
93+
return ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
94+
if (_breakpointExists(getState(), location)) {
95+
return Promise.resolve();
96+
}
97+
98+
const breakpoint = _createBreakpoint(location, referenceBreakpoint);
99+
100+
let promise = addClientBreakpoint(
101+
getState(),
102+
client,
103+
sourceMaps,
104+
breakpoint
105+
);
106+
107+
// If the breakpoint is already disabled, we need to communicate
108+
// with the server, but we also have to remove the breakpoint immediately.
109+
if (referenceBreakpoint.disabled) {
110+
promise = promise.then(args =>
111+
client
112+
.removeBreakpoint(referenceBreakpoint.id)
113+
.then(() =>
114+
Promise.resolve(Object.assign({}, args, { status: "done" }))
115+
)
116+
);
117+
}
118+
119+
const action = {
120+
type: "SYNC_BREAKPOINT",
121+
breakpoint,
122+
[PROMISE]: promise
123+
};
124+
125+
return dispatch(action);
126+
};
127+
}
128+
85129
/**
86130
* Add a new breakpoint
87131
*
@@ -92,45 +136,22 @@ export function enableBreakpoint(location: Location) {
92136
*/
93137
export function addBreakpoint(
94138
location: Location,
95-
{ condition, disabled = false }: addBreakpointOptions = {}
139+
{ condition }: addBreakpointOptions = {}
96140
) {
97141
return ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
98142
if (_breakpointExists(getState(), location)) {
99143
return Promise.resolve();
100144
}
101145

102-
const breakpoint = _createBreakpoint(location, { condition, disabled });
146+
const breakpoint = _createBreakpoint(location, { condition });
103147
const action = {
104148
type: "ADD_BREAKPOINT",
105149
breakpoint,
106-
condition: condition
150+
condition: condition,
151+
[PROMISE]: addClientBreakpoint(getState(), client, sourceMaps, breakpoint)
107152
};
108153

109-
// If the breakpoint is already disabled, we don't need to communicate
110-
// with the server. We just need to dispatch an action
111-
// simulating a successful server request
112-
if (disabled) {
113-
return dispatch(
114-
Object.assign({}, action, {
115-
status: "done",
116-
value: {
117-
id: breakpoint.id,
118-
actualLocation: breakpoint.location
119-
}
120-
})
121-
);
122-
}
123-
124-
return dispatch(
125-
Object.assign({}, action, {
126-
[PROMISE]: addClientBreakpoint(
127-
getState(),
128-
client,
129-
sourceMaps,
130-
breakpoint
131-
)
132-
})
133-
);
154+
return dispatch(action);
134155
};
135156
}
136157

src/actions/sources.js

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { PROMISE } from "../utils/redux/middleware/promise";
1414
import assert from "../utils/assert";
1515
import { updateFrameLocations } from "../utils/pause";
1616
import { setSymbols } from "./ast";
17-
import { addBreakpoint } from "./breakpoints";
17+
import { syncBreakpoint } from "./breakpoints";
1818

1919
import { prettyPrint } from "../utils/pretty-print";
2020
import { getPrettySourceURL } from "../utils/source";
@@ -51,17 +51,13 @@ async function checkPendingBreakpoint(
5151
pendingBreakpoint,
5252
source
5353
) {
54-
const {
55-
location: { line, sourceUrl, column },
56-
condition,
57-
disabled
58-
} = pendingBreakpoint;
54+
const { line, sourceUrl, column } = pendingBreakpoint.location;
5955
const sameSource = sourceUrl && sourceUrl === source.url;
6056
const location = { sourceId: source.id, sourceUrl, line, column };
6157
const bp = getBreakpoint(state, location);
6258

6359
if (sameSource && !bp) {
64-
await dispatch(addBreakpoint(location, { condition, disabled }));
60+
await dispatch(syncBreakpoint(location, pendingBreakpoint));
6561
}
6662
}
6763

src/actions/tests/helpers/breakpoints.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export function mockPendingBreakpoint(overrides = {}) {
88
line: line || 5,
99
column: column || undefined
1010
},
11-
condition: condition || "3",
11+
condition: condition || null,
1212
disabled: disabled || false
1313
};
1414
}

src/actions/tests/pending-breakpoints.js

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -172,14 +172,6 @@ describe("initializing when pending breakpoints exist in perfs", () => {
172172
const bps = selectors.getPendingBreakpoints(getState());
173173
expect(bps.size).toBe(2);
174174
});
175-
176-
it("syncs pending breakpoints", async () => {
177-
const id = makePendingLocationId(mockedPendingBreakpoint.location);
178-
const { getState } = createStore(simpleMockThreadClient);
179-
const bps = selectors.getPendingBreakpoints(getState());
180-
const bp = bps.get(id);
181-
expect(bp).toEqual(generatePendingBreakpoint(mockedPendingBreakpoint));
182-
});
183175
});
184176

185177
describe("initializing with disabled pending breakpoints in prefs", () => {
@@ -241,6 +233,49 @@ describe("adding sources", () => {
241233
bps = selectors.getBreakpoints(getState());
242234
expect(bps.size).toBe(1);
243235
});
236+
237+
it("add corresponding breakpoints for a changed source", async () => {
238+
const bp = generateBreakpoint("bar.js");
239+
const {
240+
correctedThreadClient,
241+
correctedLocation
242+
} = simulateCorrectThreadClient(2, bp.location);
243+
const { dispatch, getState } = createStore(correctedThreadClient);
244+
245+
const startBps = selectors.getBreakpoints(getState());
246+
expect(startBps.size).toBe(0);
247+
248+
const source = makeSource("bar.js");
249+
const expectedId = makeLocationId(correctedLocation);
250+
await dispatch(actions.newSource(source));
251+
252+
const endBps = selectors.getBreakpoints(getState());
253+
const returnedBp = endBps.get(expectedId);
254+
expect(returnedBp).not.toBe(bp);
255+
expect(returnedBp.location).toEqual(correctedLocation);
256+
});
257+
258+
it("updates pending breakpoints for a changed source", async () => {
259+
const bp = generateBreakpoint("bar.js");
260+
const {
261+
correctedThreadClient,
262+
correctedLocation
263+
} = simulateCorrectThreadClient(2, bp.location);
264+
const { dispatch, getState } = createStore(correctedThreadClient);
265+
const correctedBp = generateCorrectedBreakpoint(bp, correctedLocation);
266+
267+
const startBps = selectors.getPendingBreakpoints(getState());
268+
expect(startBps.size).toBe(1);
269+
270+
const source = makeSource("bar.js");
271+
const expectedId = makePendingLocationId(correctedLocation);
272+
const expectedBreakpoint = generatePendingBreakpoint(correctedBp);
273+
await dispatch(actions.newSource(source));
274+
275+
const endBps = selectors.getPendingBreakpoints(getState());
276+
const returnedBp = endBps.get(expectedId);
277+
expect(returnedBp).toEqual(expectedBreakpoint);
278+
});
244279
});
245280

246281
describe("invalid breakpoint location", () => {

src/reducers/breakpoints.js

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ function update(
8080
return newState;
8181
}
8282

83+
case "SYNC_BREAKPOINT": {
84+
const newState = syncBreakpoint(state, action);
85+
setPendingBreakpoints(newState);
86+
return newState;
87+
}
88+
8389
case "ENABLE_BREAKPOINT": {
8490
const newState = enableBreakpoint(state, action);
8591
setPendingBreakpoints(newState);
@@ -118,6 +124,57 @@ function update(
118124
return state;
119125
}
120126

127+
function _optimisticlyAddBreakpoint(state, breakpoint) {
128+
const id = makeLocationId(breakpoint.location);
129+
const updateOpts = {
130+
loading: true
131+
};
132+
133+
return state.setIn(["breakpoints", id], updateObj(breakpoint, updateOpts));
134+
}
135+
136+
function _commitBreakpoint(state, breakpoint, overrides = {}) {
137+
const location = overrides.location || breakpoint.location;
138+
const id = makeLocationId(location);
139+
const updatedOpts = Object.assign({}, { loading: false }, overrides);
140+
141+
return state.setIn(["breakpoints", id], updateObj(breakpoint, updatedOpts));
142+
}
143+
144+
function _correctBreakpoint(state, breakpoint, actualLocation) {
145+
const intermState = deleteBreakpoint(state, breakpoint.location);
146+
const location = actualLocation;
147+
const newLocationId = makeLocationId(actualLocation);
148+
const overrides = { location, id: newLocationId };
149+
150+
return _commitBreakpoint(intermState, breakpoint, overrides);
151+
}
152+
153+
function syncBreakpoint(state, action) {
154+
if (action.status === "start") {
155+
return _optimisticlyAddBreakpoint(state, action.breakpoint);
156+
}
157+
158+
if (action.status === "done") {
159+
const { breakpoint, value: { actualLocation } } = action;
160+
const sameLocation = !locationMoved(breakpoint.location, actualLocation);
161+
162+
if (sameLocation) {
163+
return _commitBreakpoint(state, breakpoint, action.value);
164+
}
165+
166+
const updatedState = _correctBreakpoint(state, breakpoint, actualLocation);
167+
const id = makeLocationId(actualLocation);
168+
const correctBreakpoint = updatedState.breakpoints.get(id);
169+
return updatePendingBreakpoint(updatedState, correctBreakpoint);
170+
}
171+
172+
if (action.status === "error") {
173+
// Remove the optimistic update and pending breakpoint
174+
return deleteBreakpoint(state, action.breakpoint.location);
175+
}
176+
}
177+
121178
function addBreakpoint(state, action) {
122179
const id = makeLocationId(action.breakpoint.location);
123180
if (action.status === "start") {
@@ -197,7 +254,10 @@ function disableBreakpoint(state, action) {
197254
return updatePendingBreakpoint(updatedState, breakpoint);
198255
}
199256

200-
function deleteBreakpoint(state, id, pendingId) {
257+
function deleteBreakpoint(state, location) {
258+
const id = makeLocationId(location);
259+
const pendingId = makePendingLocationId(location);
260+
201261
return state
202262
.deleteIn(["breakpoints", id])
203263
.deleteIn(["pendingBreakpoints", pendingId]);
@@ -208,10 +268,7 @@ function removeBreakpoint(state, action) {
208268
return state;
209269
}
210270

211-
const id = makeLocationId(action.breakpoint.location);
212-
const pendingId = makePendingLocationId(action.breakpoint.location);
213-
214-
const updatedState = deleteBreakpoint(state, id, pendingId);
271+
const updatedState = deleteBreakpoint(state, action.breakpoint.location);
215272

216273
return updatedState.set(
217274
"breakpointsDisabled",

0 commit comments

Comments
 (0)