Skip to content

Commit 70e2431

Browse files
authored
Refactor how messages are posted to reducers and to the extension (#10019)
Rather than having a developer call create and then arg.queue, this replaces that with one function. Hides the intricacies of how something is posted or queued. Also allows us to add additional logic to control what messages can be posted (for synchronization) instead of developer having to do this in every reducer. Simple harmless refactor
1 parent 01e402c commit 70e2431

File tree

11 files changed

+209
-200
lines changed

11 files changed

+209
-200
lines changed

src/client/datascience/interactive-common/synchronization.ts

Lines changed: 107 additions & 104 deletions
Large diffs are not rendered by default.

src/datascience-ui/history-react/redux/reducers/creation.ts

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Identifiers } from '../../../../client/datascience/constants';
55
import { InteractiveWindowMessages } from '../../../../client/datascience/interactive-common/interactiveWindowTypes';
66
import { ICell, IDataScienceExtraSettings } from '../../../../client/datascience/types';
77
import { createCellVM, extractInputText, ICellViewModel, IMainState } from '../../../interactive-common/mainState';
8-
import { createPostableAction } from '../../../interactive-common/redux/helpers';
8+
import { postActionToExtension } from '../../../interactive-common/redux/helpers';
99
import { Helpers } from '../../../interactive-common/redux/reducers/helpers';
1010
import { IAddCellAction, ICellAction } from '../../../interactive-common/redux/reducers/types';
1111
import { InteractiveReducerArg } from '../mapping';
@@ -85,17 +85,15 @@ export namespace Creation {
8585
const cellVM = result.cellVMs[result.cellVMs.length - 1];
8686

8787
// We're adding a new cell here. Tell the intellisense engine we have a new cell
88-
arg.queueAction(
89-
createPostableAction(InteractiveWindowMessages.UpdateModel, {
90-
source: 'user',
91-
kind: 'add',
92-
oldDirty: arg.prevState.dirty,
93-
newDirty: true,
94-
cell: cellVM.cell,
95-
fullText: extractInputText(cellVM, result.settings),
96-
currentText: cellVM.inputBlockText
97-
})
98-
);
88+
postActionToExtension(arg, InteractiveWindowMessages.UpdateModel, {
89+
source: 'user',
90+
kind: 'add',
91+
oldDirty: arg.prevState.dirty,
92+
newDirty: true,
93+
cell: cellVM.cell,
94+
fullText: extractInputText(cellVM, result.settings),
95+
currentText: cellVM.inputBlockText
96+
});
9997
}
10098

10199
return result;
@@ -119,7 +117,7 @@ export namespace Creation {
119117

120118
export function deleteAllCells(arg: InteractiveReducerArg<IAddCellAction>): IMainState {
121119
// Send messages to other side to indicate the deletes
122-
arg.queueAction(createPostableAction(InteractiveWindowMessages.DeleteAllCells));
120+
postActionToExtension(arg, InteractiveWindowMessages.DeleteAllCells);
123121

124122
return {
125123
...arg.prevState,
@@ -132,16 +130,14 @@ export namespace Creation {
132130
const index = arg.prevState.cellVMs.findIndex(c => c.cell.id === arg.payload.data.cellId);
133131
if (index >= 0 && arg.payload.data.cellId) {
134132
// Send messages to other side to indicate the delete
135-
arg.queueAction(
136-
createPostableAction(InteractiveWindowMessages.UpdateModel, {
137-
source: 'user',
138-
kind: 'remove',
139-
index,
140-
oldDirty: arg.prevState.dirty,
141-
newDirty: true,
142-
cell: arg.prevState.cellVMs[index].cell
143-
})
144-
);
133+
postActionToExtension(arg, InteractiveWindowMessages.UpdateModel, {
134+
source: 'user',
135+
kind: 'remove',
136+
index,
137+
oldDirty: arg.prevState.dirty,
138+
newDirty: true,
139+
cell: arg.prevState.cellVMs[index].cell
140+
});
145141

146142
const newVMs = arg.prevState.cellVMs.filter((_c, i) => i !== index);
147143
return {

src/datascience-ui/history-react/redux/reducers/effects.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { IScrollToCell } from '../../../../client/datascience/interactive-common
66
import { CssMessages } from '../../../../client/datascience/messages';
77
import { IDataScienceExtraSettings } from '../../../../client/datascience/types';
88
import { IMainState } from '../../../interactive-common/mainState';
9-
import { createPostableAction } from '../../../interactive-common/redux/helpers';
9+
import { postActionToExtension } from '../../../interactive-common/redux/helpers';
1010
import { Helpers } from '../../../interactive-common/redux/reducers/helpers';
1111
import { ICellAction, IScrollAction } from '../../../interactive-common/redux/reducers/types';
1212
import { computeEditorOptions } from '../../../react-common/settingsReactSide';
@@ -62,8 +62,8 @@ export namespace Effects {
6262
if (newSettings && newSettings.extraSettings && newSettings.extraSettings.theme !== arg.prevState.vscodeThemeName) {
6363
const knownDark = Helpers.computeKnownDark(newSettings);
6464
// User changed the current theme. Rerender
65-
arg.queueAction(createPostableAction(CssMessages.GetCssRequest, { isDark: knownDark }));
66-
arg.queueAction(createPostableAction(CssMessages.GetMonacoThemeRequest, { isDark: knownDark }));
65+
postActionToExtension(arg, CssMessages.GetCssRequest, { isDark: knownDark });
66+
postActionToExtension(arg, CssMessages.GetMonacoThemeRequest, { isDark: knownDark });
6767
}
6868

6969
// Update our input cell state if the user changed this setting

src/datascience-ui/history-react/redux/reducers/execution.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { CellState } from '../../../../client/datascience/types';
1111
import { generateMarkdownFromCodeLines } from '../../../common';
1212
import { createCellFrom } from '../../../common/cellFactory';
1313
import { createCellVM, IMainState } from '../../../interactive-common/mainState';
14-
import { createPostableAction } from '../../../interactive-common/redux/helpers';
14+
import { postActionToExtension } from '../../../interactive-common/redux/helpers';
1515
import { Helpers } from '../../../interactive-common/redux/reducers/helpers';
1616
import { ICodeAction } from '../../../interactive-common/redux/reducers/types';
1717
import { InteractiveReducerArg } from '../mapping';
@@ -24,7 +24,7 @@ export namespace Execution {
2424
const cells = arg.prevState.undoStack[arg.prevState.undoStack.length - 1];
2525
const undoStack = arg.prevState.undoStack.slice(0, arg.prevState.undoStack.length - 1);
2626
const redoStack = Helpers.pushStack(arg.prevState.redoStack, arg.prevState.cellVMs);
27-
arg.queueAction(createPostableAction(InteractiveWindowMessages.Undo));
27+
postActionToExtension(arg, InteractiveWindowMessages.Undo);
2828
return {
2929
...arg.prevState,
3030
cellVMs: cells,
@@ -43,7 +43,7 @@ export namespace Execution {
4343
const cells = arg.prevState.redoStack[arg.prevState.redoStack.length - 1];
4444
const redoStack = arg.prevState.redoStack.slice(0, arg.prevState.redoStack.length - 1);
4545
const undoStack = Helpers.pushStack(arg.prevState.undoStack, arg.prevState.cellVMs);
46-
arg.queueAction(createPostableAction(InteractiveWindowMessages.Redo));
46+
postActionToExtension(arg, InteractiveWindowMessages.Redo);
4747
return {
4848
...arg.prevState,
4949
cellVMs: cells,
@@ -107,7 +107,7 @@ export namespace Execution {
107107

108108
// Send a message to execute this code if necessary.
109109
if (newCell.cell.state !== CellState.finished) {
110-
arg.queueAction(createPostableAction(InteractiveWindowMessages.SubmitNewCell, { code: arg.payload.data.code, id: newCell.cell.id }));
110+
postActionToExtension(arg, InteractiveWindowMessages.SubmitNewCell, { code: arg.payload.data.code, id: newCell.cell.id });
111111
}
112112

113113
// Stick in a new cell at the bottom that's editable and update our state

src/datascience-ui/interactive-common/redux/helpers.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import * as Redux from 'redux';
77
import { IInteractiveWindowMapping, InteractiveWindowMessages } from '../../../client/datascience/interactive-common/interactiveWindowTypes';
88
import { BaseReduxActionPayload } from '../../../client/datascience/interactive-common/types';
99
import { CssMessages, SharedMessages } from '../../../client/datascience/messages';
10+
import { QueueAnotherFunc } from '../../react-common/reduxUtils';
1011
import { CommonAction, CommonActionType, CommonActionTypeMapping } from './reducers/types';
1112

1213
const AllowedMessages = [...Object.values(InteractiveWindowMessages), ...Object.values(CssMessages), ...Object.values(SharedMessages), ...Object.values(CommonActionType)];
@@ -26,14 +27,31 @@ export function createIncomingAction(type: CommonActionType | InteractiveWindowM
2627
return { type, payload: { messageDirection: 'incoming', data: undefined } };
2728
}
2829

29-
// Actions created from messages
30-
export function createPostableAction<M extends IInteractiveWindowMapping, T extends keyof M = keyof M>(message: T, payload?: M[T]): Redux.AnyAction {
31-
const newPayload: BaseReduxActionPayload<M[T]> = ({
30+
type ReducerArg = {
31+
// tslint:disable-next-line: no-any
32+
queueAction: QueueAnotherFunc<any>;
33+
// tslint:disable-next-line: no-any
34+
payload?: BaseReduxActionPayload<any>;
35+
};
36+
/**
37+
* Post a message to the extension (via dispatcher actions).
38+
*/
39+
export function postActionToExtension<K, M extends IInteractiveWindowMapping, T extends keyof M = keyof M>(originalReducerArg: ReducerArg, message: T, payload?: M[T]): void;
40+
/**
41+
* Post a message to the extension (via dispatcher actions).
42+
*/
43+
// tslint:disable-next-line: unified-signatures
44+
export function postActionToExtension<K, M extends IInteractiveWindowMapping, T extends keyof M = keyof M>(originalReducerArg: ReducerArg, message: T, payload?: M[T]): void;
45+
// tslint:disable-next-line: no-any
46+
export function postActionToExtension(originalReducerArg: ReducerArg, message: any, payload?: any) {
47+
// tslint:disable-next-line: no-any
48+
const newPayload: BaseReduxActionPayload<any> = ({
3249
data: payload,
3350
messageDirection: 'outgoing'
3451
// tslint:disable-next-line: no-any
35-
} as any) as BaseReduxActionPayload<M[T]>;
36-
return { type: CommonActionType.PostOutgoingMessage, payload: { payload: newPayload, type: message } };
52+
} as any) as BaseReduxActionPayload<any>;
53+
const action = { type: CommonActionType.PostOutgoingMessage, payload: { payload: newPayload, type: message } };
54+
originalReducerArg.queueAction(action);
3755
}
3856
export function unwrapPostableAction(action: Redux.AnyAction): { type: keyof IInteractiveWindowMapping; payload?: BaseReduxActionPayload<{}> } {
3957
// Unwrap the payload that was created in `createPostableAction`.

src/datascience-ui/interactive-common/redux/reducers/kernel.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,23 @@
44
import { InteractiveWindowMessages } from '../../../../client/datascience/interactive-common/interactiveWindowTypes';
55
import { CellState } from '../../../../client/datascience/types';
66
import { IMainState, IServerState } from '../../mainState';
7-
import { createPostableAction } from '../helpers';
7+
import { postActionToExtension } from '../helpers';
88
import { CommonActionType, CommonReducerArg } from './types';
99

1010
export namespace Kernel {
1111
// tslint:disable-next-line: no-any
1212
export function selectKernel(arg: CommonReducerArg<CommonActionType | InteractiveWindowMessages, IServerState | undefined>): IMainState {
13-
arg.queueAction(createPostableAction(InteractiveWindowMessages.SelectKernel));
13+
postActionToExtension(arg, InteractiveWindowMessages.SelectKernel);
1414

1515
return arg.prevState;
1616
}
1717
export function selectJupyterURI(arg: CommonReducerArg): IMainState {
18-
arg.queueAction(createPostableAction(InteractiveWindowMessages.SelectJupyterServer));
18+
postActionToExtension(arg, InteractiveWindowMessages.SelectJupyterServer);
1919

2020
return arg.prevState;
2121
}
2222
export function restartKernel(arg: CommonReducerArg): IMainState {
23-
arg.queueAction(createPostableAction(InteractiveWindowMessages.RestartKernel));
23+
postActionToExtension(arg, InteractiveWindowMessages.RestartKernel);
2424

2525
// Set busy until kernel is restarted
2626
return {
@@ -30,7 +30,7 @@ export namespace Kernel {
3030
}
3131

3232
export function interruptKernel(arg: CommonReducerArg): IMainState {
33-
arg.queueAction(createPostableAction(InteractiveWindowMessages.Interrupt));
33+
postActionToExtension(arg, InteractiveWindowMessages.Interrupt);
3434

3535
// Set busy until kernel is finished interrupting
3636
return {

src/datascience-ui/interactive-common/redux/reducers/transfer.ts

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ import { IEditorContentChange, InteractiveWindowMessages, NotebookModelChange }
66
import { CssMessages } from '../../../../client/datascience/messages';
77
import { ICell } from '../../../../client/datascience/types';
88
import { extractInputText, getSelectedAndFocusedInfo, IMainState } from '../../mainState';
9-
import { createPostableAction } from '../helpers';
9+
import { postActionToExtension } from '../helpers';
1010
import { Helpers } from './helpers';
1111
import { CommonActionType, CommonReducerArg, ICellAction, IEditCellAction, ILinkClickAction, ISendCommandAction, IShowDataViewerAction } from './types';
1212

1313
// These are all reducers that don't actually change state. They merely dispatch a message to the other side.
1414
export namespace Transfer {
1515
export function exportCells(arg: CommonReducerArg): IMainState {
1616
const cellContents = arg.prevState.cellVMs.map(v => v.cell);
17-
arg.queueAction(createPostableAction(InteractiveWindowMessages.Export, cellContents));
17+
postActionToExtension(arg, InteractiveWindowMessages.Export, cellContents);
1818

1919
// Indicate busy
2020
return {
@@ -27,46 +27,46 @@ export namespace Transfer {
2727
// Note: this is assuming editor contents have already been saved. That should happen as a result of focus change
2828

2929
// Actually waiting for save results before marking as not dirty, so don't do it here.
30-
arg.queueAction(createPostableAction(InteractiveWindowMessages.SaveAll, { cells: arg.prevState.cellVMs.map(cvm => cvm.cell) }));
30+
postActionToExtension(arg, InteractiveWindowMessages.SaveAll, { cells: arg.prevState.cellVMs.map(cvm => cvm.cell) });
3131
return arg.prevState;
3232
}
3333

3434
export function showDataViewer(arg: CommonReducerArg<CommonActionType, IShowDataViewerAction>): IMainState {
35-
arg.queueAction(createPostableAction(InteractiveWindowMessages.ShowDataViewer, { variable: arg.payload.data.variable, columnSize: arg.payload.data.columnSize }));
35+
postActionToExtension(arg, InteractiveWindowMessages.ShowDataViewer, { variable: arg.payload.data.variable, columnSize: arg.payload.data.columnSize });
3636
return arg.prevState;
3737
}
3838

3939
export function sendCommand(arg: CommonReducerArg<CommonActionType, ISendCommandAction>): IMainState {
40-
arg.queueAction(createPostableAction(InteractiveWindowMessages.NativeCommand, { command: arg.payload.data.command, source: arg.payload.data.commandType }));
40+
postActionToExtension(arg, InteractiveWindowMessages.NativeCommand, { command: arg.payload.data.command, source: arg.payload.data.commandType });
4141
return arg.prevState;
4242
}
4343

4444
export function showPlot(arg: CommonReducerArg<CommonActionType | InteractiveWindowMessages, string | undefined>): IMainState {
4545
if (arg.payload.data) {
46-
arg.queueAction(createPostableAction(InteractiveWindowMessages.ShowPlot, arg.payload.data));
46+
postActionToExtension(arg, InteractiveWindowMessages.ShowPlot, arg.payload.data);
4747
}
4848
return arg.prevState;
4949
}
5050

5151
export function linkClick(arg: CommonReducerArg<CommonActionType, ILinkClickAction>): IMainState {
5252
if (arg.payload.data.href.startsWith('data:image/png')) {
53-
arg.queueAction(createPostableAction(InteractiveWindowMessages.SavePng, arg.payload.data.href));
53+
postActionToExtension(arg, InteractiveWindowMessages.SavePng, arg.payload.data.href);
5454
} else {
55-
arg.queueAction(createPostableAction(InteractiveWindowMessages.OpenLink, arg.payload.data.href));
55+
postActionToExtension(arg, InteractiveWindowMessages.OpenLink, arg.payload.data.href);
5656
}
5757
return arg.prevState;
5858
}
5959

6060
export function getAllCells(arg: CommonReducerArg): IMainState {
6161
const cells = arg.prevState.cellVMs.map(c => c.cell);
62-
arg.queueAction(createPostableAction(InteractiveWindowMessages.ReturnAllCells, cells));
62+
postActionToExtension(arg, InteractiveWindowMessages.ReturnAllCells, cells);
6363
return arg.prevState;
6464
}
6565

6666
export function gotoCell(arg: CommonReducerArg<CommonActionType, ICellAction>): IMainState {
6767
const cellVM = arg.prevState.cellVMs.find(c => c.cell.id === arg.payload.data.cellId);
6868
if (cellVM && cellVM.cell.data.cell_type === 'code') {
69-
arg.queueAction(createPostableAction(InteractiveWindowMessages.GotoCodeCell, { file: cellVM.cell.file, line: cellVM.cell.line }));
69+
postActionToExtension(arg, InteractiveWindowMessages.GotoCodeCell, { file: cellVM.cell.file, line: cellVM.cell.line });
7070
}
7171
return arg.prevState;
7272
}
@@ -79,7 +79,7 @@ export namespace Transfer {
7979

8080
// Send a message to the other side to jump to a particular cell
8181
if (cellVM) {
82-
arg.queueAction(createPostableAction(InteractiveWindowMessages.CopyCodeCell, { source: extractInputText(cellVM, arg.prevState.settings) }));
82+
postActionToExtension(arg, InteractiveWindowMessages.CopyCodeCell, { source: extractInputText(cellVM, arg.prevState.settings) });
8383
}
8484

8585
return arg.prevState;
@@ -88,13 +88,13 @@ export namespace Transfer {
8888
export function gather(arg: CommonReducerArg<CommonActionType, ICellAction>): IMainState {
8989
const cellVM = arg.prevState.cellVMs.find(c => c.cell.id === arg.payload.data.cellId);
9090
if (cellVM) {
91-
arg.queueAction(createPostableAction(InteractiveWindowMessages.GatherCodeRequest, cellVM.cell));
91+
postActionToExtension(arg, InteractiveWindowMessages.GatherCodeRequest, cellVM.cell);
9292
}
9393
return arg.prevState;
9494
}
9595

9696
function postModelUpdate<T>(arg: CommonReducerArg<CommonActionType, T>, update: NotebookModelChange) {
97-
arg.queueAction(createPostableAction(InteractiveWindowMessages.UpdateModel, update));
97+
postActionToExtension(arg, InteractiveWindowMessages.UpdateModel, update);
9898
}
9999

100100
export function postModelEdit<T>(arg: CommonReducerArg<CommonActionType, T>, forward: IEditorContentChange[], reverse: IEditorContentChange[], id: string) {
@@ -199,16 +199,16 @@ export namespace Transfer {
199199

200200
export function started(arg: CommonReducerArg): IMainState {
201201
// Send all of our initial requests
202-
arg.queueAction(createPostableAction(InteractiveWindowMessages.Started));
203-
arg.queueAction(createPostableAction(CssMessages.GetCssRequest, { isDark: arg.prevState.baseTheme !== 'vscode-light' }));
204-
arg.queueAction(createPostableAction(CssMessages.GetMonacoThemeRequest, { isDark: arg.prevState.baseTheme !== 'vscode-light' }));
205-
arg.queueAction(createPostableAction(InteractiveWindowMessages.LoadOnigasmAssemblyRequest));
206-
arg.queueAction(createPostableAction(InteractiveWindowMessages.LoadTmLanguageRequest));
202+
postActionToExtension(arg, InteractiveWindowMessages.Started);
203+
postActionToExtension(arg, CssMessages.GetCssRequest, { isDark: arg.prevState.baseTheme !== 'vscode-light' });
204+
postActionToExtension(arg, CssMessages.GetMonacoThemeRequest, { isDark: arg.prevState.baseTheme !== 'vscode-light' });
205+
postActionToExtension(arg, InteractiveWindowMessages.LoadOnigasmAssemblyRequest);
206+
postActionToExtension(arg, InteractiveWindowMessages.LoadTmLanguageRequest);
207207
return arg.prevState;
208208
}
209209

210210
export function loadedAllCells(arg: CommonReducerArg): IMainState {
211-
arg.queueAction(createPostableAction(InteractiveWindowMessages.LoadAllCellsComplete, { cells: arg.prevState.cellVMs.map(c => c.cell) }));
211+
postActionToExtension(arg, InteractiveWindowMessages.LoadAllCellsComplete, { cells: arg.prevState.cellVMs.map(c => c.cell) });
212212
return arg.prevState;
213213
}
214214
}

0 commit comments

Comments
 (0)