Skip to content

Commit 666e07d

Browse files
authored
Ensure we have a base type for all action payloads (#9840)
For #9340 Ensures all actions have a base type, to pass information such whether the action was invoked to sync state for multiple editors (pointing to same file) in same session or across sessions. This PR only adds the ability to pass such new information to all actions.
1 parent bb95b58 commit 666e07d

File tree

30 files changed

+604
-751
lines changed

30 files changed

+604
-751
lines changed

src/client/datascience/data-viewing/types.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
'use strict';
44
import { JSONObject } from '@phosphor/coreutils';
55

6-
import { CssMessages, IGetCssRequest, IGetCssResponse, SharedMessages } from '../messages';
6+
import { SharedMessages } from '../messages';
77
import { IJupyterVariable } from '../types';
88

99
export const CellFetchAllLimit = 100000;
@@ -40,15 +40,13 @@ export interface IGetRowsResponse {
4040
}
4141

4242
// Map all messages to specific payloads
43-
export class IDataViewerMapping {
44-
public [DataViewerMessages.Started]: never | undefined;
45-
public [DataViewerMessages.UpdateSettings]: string;
46-
public [DataViewerMessages.InitializeData]: IJupyterVariable;
47-
public [DataViewerMessages.GetAllRowsRequest]: never | undefined;
48-
public [DataViewerMessages.GetAllRowsResponse]: JSONObject;
49-
public [DataViewerMessages.GetRowsRequest]: IGetRowsRequest;
50-
public [DataViewerMessages.GetRowsResponse]: IGetRowsResponse;
51-
public [DataViewerMessages.CompletedData]: never | undefined;
52-
public [CssMessages.GetCssRequest]: IGetCssRequest;
53-
public [CssMessages.GetCssResponse]: IGetCssResponse;
54-
}
43+
export type IDataViewerMapping = {
44+
[DataViewerMessages.Started]: never | undefined;
45+
[DataViewerMessages.UpdateSettings]: string;
46+
[DataViewerMessages.InitializeData]: IJupyterVariable;
47+
[DataViewerMessages.GetAllRowsRequest]: never | undefined;
48+
[DataViewerMessages.GetAllRowsResponse]: JSONObject;
49+
[DataViewerMessages.GetRowsRequest]: IGetRowsRequest;
50+
[DataViewerMessages.GetRowsResponse]: IGetRowsResponse;
51+
[DataViewerMessages.CompletedData]: never | undefined;
52+
};

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
'use strict';
44
import * as monacoEditor from 'monaco-editor/esm/vs/editor/editor.api';
55
import { IServerState } from '../../../datascience-ui/interactive-common/mainState';
6-
import { IAddCellAction } from '../../../datascience-ui/interactive-common/redux/reducers/types';
7-
import { CssMessages, IGetCssRequest, IGetCssResponse, IGetMonacoThemeRequest } from '../messages';
6+
import { IAddCellAction, ICellAction } from '../../../datascience-ui/interactive-common/redux/reducers/types';
7+
import { CssMessages, IGetCssRequest, IGetCssResponse, IGetMonacoThemeRequest, SharedMessages } from '../messages';
8+
import { IGetMonacoThemeResponse } from '../monacoMessages';
89
import { ICell, IInteractiveWindowInfo, IJupyterVariable, IJupyterVariablesRequest, IJupyterVariablesResponse } from '../types';
910

1011
export enum InteractiveWindowMessages {
@@ -305,9 +306,9 @@ export class IInteractiveWindowMapping {
305306
public [InteractiveWindowMessages.SelectKernel]: IServerState | undefined;
306307
public [InteractiveWindowMessages.SelectJupyterServer]: never | undefined;
307308
public [InteractiveWindowMessages.Export]: ICell[];
308-
public [InteractiveWindowMessages.GetAllCells]: ICell;
309+
public [InteractiveWindowMessages.GetAllCells]: never | undefined;
309310
public [InteractiveWindowMessages.ReturnAllCells]: ICell[];
310-
public [InteractiveWindowMessages.DeleteCell]: never | undefined;
311+
public [InteractiveWindowMessages.DeleteCell]: ICellAction;
311312
public [InteractiveWindowMessages.DeleteAllCells]: IAddCellAction;
312313
public [InteractiveWindowMessages.Undo]: never | undefined;
313314
public [InteractiveWindowMessages.Redo]: never | undefined;
@@ -331,6 +332,7 @@ export class IInteractiveWindowMapping {
331332
public [CssMessages.GetCssRequest]: IGetCssRequest;
332333
public [CssMessages.GetCssResponse]: IGetCssResponse;
333334
public [CssMessages.GetMonacoThemeRequest]: IGetMonacoThemeRequest;
335+
public [CssMessages.GetMonacoThemeResponse]: IGetMonacoThemeResponse;
334336
public [InteractiveWindowMessages.ProvideCompletionItemsRequest]: IProvideCompletionItemsRequest;
335337
public [InteractiveWindowMessages.CancelCompletionItemsRequest]: ICancelIntellisenseRequest;
336338
public [InteractiveWindowMessages.ProvideCompletionItemsResponse]: IProvideCompletionItemsResponse;
@@ -370,11 +372,14 @@ export class IInteractiveWindowMapping {
370372
public [InteractiveWindowMessages.VariablesComplete]: never | undefined;
371373
public [InteractiveWindowMessages.NotebookRunAllCells]: never | undefined;
372374
public [InteractiveWindowMessages.NotebookRunSelectedCell]: never | undefined;
373-
public [InteractiveWindowMessages.NotebookAddCellBelow]: never | undefined;
375+
public [InteractiveWindowMessages.NotebookAddCellBelow]: IAddCellAction;
376+
public [InteractiveWindowMessages.DoSave]: never | undefined;
374377
public [InteractiveWindowMessages.ExecutionRendered]: IRenderComplete;
375378
public [InteractiveWindowMessages.FocusedCellEditor]: IFocusedCellEditor;
376379
public [InteractiveWindowMessages.UnfocusedCellEditor]: never | undefined;
377380
public [InteractiveWindowMessages.MonacoReady]: never | undefined;
378381
public [InteractiveWindowMessages.ClearAllOutputs]: never | undefined;
379-
public [InteractiveWindowMessages.UpdateKernel]: IServerState | undefined;
382+
public [InteractiveWindowMessages.UpdateKernel]: IServerState;
383+
public [SharedMessages.UpdateSettings]: string;
384+
public [SharedMessages.LocInit]: string;
380385
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
'use strict';
5+
6+
// Stuff common to React and Extensions.
7+
8+
type BaseData = {
9+
/**
10+
* If this property exists, then this is an action that has been dispatched for the solve purpose of:
11+
* 1. Synchronizing states across different editors (pointing to the same file).
12+
* 2. Synchronizing states across different editors (pointing to the same file) in different sessions.
13+
*
14+
* @type {('syncEditors' | 'syncSessions')}
15+
*/
16+
broadcastReason?: 'syncEditors' | 'syncSessions';
17+
/**
18+
* Tells us whether this message is incoming for reducer use or
19+
* whether this is a message that needs to be sent out to extension (from reducer).
20+
*/
21+
messageDirection?: 'incoming' | 'outgoing';
22+
};
23+
24+
type BaseDataWithPayload<T> = {
25+
/**
26+
* If this property exists, then this is an action that has been dispatched for the solve purpose of:
27+
* 1. Synchronizing states across different editors (pointing to the same file).
28+
* 2. Synchronizing states across different editors (pointing to the same file) in different sessions.
29+
*
30+
* @type {('syncEditors' | 'syncSessions')}
31+
*/
32+
broadcastReason?: 'syncEditors' | 'syncSessions';
33+
/**
34+
* Tells us whether this message is incoming for reducer use or
35+
* whether this is a message that needs to be sent out to extension (from reducer).
36+
*/
37+
messageDirection?: 'incoming' | 'outgoing';
38+
data: T;
39+
};
40+
41+
// This forms the base content of every payload in all dispatchers.
42+
export type BaseReduxActionPayload<T = never | undefined> = T extends never ? (T extends undefined ? BaseData : BaseDataWithPayload<T>) : BaseDataWithPayload<T>;

src/client/datascience/messages.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@
22
// Licensed under the MIT License.
33
'use strict';
44

5-
export namespace CssMessages {
6-
export const GetCssRequest = 'get_css_request';
7-
export const GetCssResponse = 'get_css_response';
8-
export const GetMonacoThemeRequest = 'get_monaco_theme_request';
9-
export const GetMonacoThemeResponse = 'get_monaco_theme_response';
5+
export enum CssMessages {
6+
GetCssRequest = 'get_css_request',
7+
GetCssResponse = 'get_css_response',
8+
GetMonacoThemeRequest = 'get_monaco_theme_request',
9+
GetMonacoThemeResponse = 'get_monaco_theme_response'
1010
}
1111

12-
export namespace SharedMessages {
13-
export const UpdateSettings = 'update_settings';
14-
export const Started = 'started';
15-
export const LocInit = 'loc_init';
16-
export const StyleUpdate = 'style_update';
12+
export enum SharedMessages {
13+
UpdateSettings = 'update_settings',
14+
Started = 'started',
15+
LocInit = 'loc_init',
16+
StyleUpdate = 'style_update'
1717
}
1818

1919
export interface IGetCssRequest {

src/datascience-ui/data-explorer/mainPanel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export class MainPanel extends React.Component<IMainPanelProps, IMainPanelState>
9494
this.postOffice.addHandler(this);
9595

9696
// Tell the dataviewer code we have started.
97-
this.postOffice.sendMessage<IDataViewerMapping, 'started'>(DataViewerMessages.Started);
97+
this.postOffice.sendMessage<IDataViewerMapping>(DataViewerMessages.Started);
9898
}
9999

100100
public componentWillUnmount() {

src/datascience-ui/history-react/redux/actions.ts

Lines changed: 39 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,60 +3,57 @@
33
'use strict';
44
import * as monacoEditor from 'monaco-editor/esm/vs/editor/editor.api';
55

6-
import { IRefreshVariablesRequest } from '../../../client/datascience/interactive-common/interactiveWindowTypes';
6+
import { InteractiveWindowMessages, IRefreshVariablesRequest } from '../../../client/datascience/interactive-common/interactiveWindowTypes';
77
import { IJupyterVariable, IJupyterVariablesRequest } from '../../../client/datascience/types';
88
import {
99
CommonAction,
1010
CommonActionType,
11+
createIncomingAction,
12+
createIncomingActionWithPayload,
1113
ICellAction,
1214
ICodeAction,
1315
ICodeCreatedAction,
1416
IEditCellAction,
1517
ILinkClickAction,
1618
IScrollAction,
17-
IShowDataViewerAction,
18-
IShowPlotAction
19+
IShowDataViewerAction
1920
} from '../../interactive-common/redux/reducers/types';
2021

2122
// See https://react-redux.js.org/using-react-redux/connect-mapdispatch#defining-mapdispatchtoprops-as-an-object
2223
export const actionCreators = {
23-
refreshVariables: (newExecutionCount?: number): CommonAction<IRefreshVariablesRequest> => ({ type: CommonActionType.REFRESH_VARIABLES, payload: { newExecutionCount } }),
24-
restartKernel: (): CommonAction<never | undefined> => ({ type: CommonActionType.RESTART_KERNEL }),
25-
interruptKernel: (): CommonAction<never | undefined> => ({ type: CommonActionType.INTERRUPT_KERNEL }),
26-
deleteAllCells: (): CommonAction<never | undefined> => ({ type: CommonActionType.DELETE_ALL_CELLS }),
27-
deleteCell: (cellId: string): CommonAction<ICellAction> => ({ type: CommonActionType.DELETE_CELL, payload: { cellId } }),
28-
undo: (): CommonAction<never | undefined> => ({ type: CommonActionType.UNDO }),
29-
redo: (): CommonAction<never | undefined> => ({ type: CommonActionType.REDO }),
30-
linkClick: (href: string): CommonAction<ILinkClickAction> => ({ type: CommonActionType.LINK_CLICK, payload: { href } }),
31-
showPlot: (imageHtml: string): CommonAction<IShowPlotAction> => ({ type: CommonActionType.SHOW_PLOT, payload: { imageHtml } }),
32-
toggleInputBlock: (cellId: string): CommonAction<ICellAction> => ({ type: CommonActionType.TOGGLE_INPUT_BLOCK, payload: { cellId } }),
33-
gotoCell: (cellId: string): CommonAction<ICellAction> => ({ type: CommonActionType.GOTO_CELL, payload: { cellId } }),
34-
copyCellCode: (cellId: string): CommonAction<ICellAction> => ({ type: CommonActionType.COPY_CELL_CODE, payload: { cellId } }),
35-
gatherCell: (cellId: string): CommonAction<ICellAction> => ({ type: CommonActionType.GATHER_CELL, payload: { cellId } }),
36-
clickCell: (cellId: string): CommonAction<ICellAction> => ({ type: CommonActionType.CLICK_CELL, payload: { cellId } }),
37-
doubleClickCell: (cellId: string): CommonAction<ICellAction> => ({ type: CommonActionType.DOUBLE_CLICK_CELL, payload: { cellId } }),
38-
editCell: (cellId: string, changes: monacoEditor.editor.IModelContentChange[], modelId: string, code: string): CommonAction<IEditCellAction> => ({
39-
type: CommonActionType.EDIT_CELL,
40-
payload: { cellId, changes, modelId, code }
41-
}),
42-
submitInput: (code: string, cellId: string): CommonAction<ICodeAction> => ({ type: CommonActionType.SUBMIT_INPUT, payload: { code, cellId } }),
43-
toggleVariableExplorer: (): CommonAction<never | undefined> => ({ type: CommonActionType.TOGGLE_VARIABLE_EXPLORER }),
44-
expandAll: (): CommonAction<never | undefined> => ({ type: CommonActionType.EXPAND_ALL }),
45-
collapseAll: (): CommonAction<never | undefined> => ({ type: CommonActionType.COLLAPSE_ALL }),
46-
export: (): CommonAction<never | undefined> => ({ type: CommonActionType.EXPORT }),
47-
showDataViewer: (variable: IJupyterVariable, columnSize: number): CommonAction<IShowDataViewerAction> => ({
48-
type: CommonActionType.SHOW_DATA_VIEWER,
49-
payload: { variable, columnSize }
50-
}),
51-
editorLoaded: (): CommonAction<never | undefined> => ({ type: CommonActionType.EDITOR_LOADED }),
52-
scroll: (isAtBottom: boolean): CommonAction<IScrollAction> => ({ type: CommonActionType.SCROLL, payload: { isAtBottom } }),
53-
unfocus: (cellId: string | undefined): CommonAction<ICellAction> => ({ type: CommonActionType.UNFOCUS_CELL, payload: { cellId } }),
54-
codeCreated: (cellId: string | undefined, modelId: string): CommonAction<ICodeCreatedAction> => ({ type: CommonActionType.CODE_CREATED, payload: { cellId, modelId } }),
55-
editorUnmounted: (): CommonAction<never | undefined> => ({ type: CommonActionType.UNMOUNT }),
56-
selectKernel: (): CommonAction<never | undefined> => ({ type: CommonActionType.SELECT_KERNEL }),
57-
selectServer: (): CommonAction<never | undefined> => ({ type: CommonActionType.SELECT_SERVER }),
58-
getVariableData: (newExecutionCount: number, startIndex: number = 0, pageSize: number = 100): CommonAction<IJupyterVariablesRequest> => ({
59-
type: CommonActionType.GET_VARIABLE_DATA,
60-
payload: { executionCount: newExecutionCount, sortColumn: 'name', sortAscending: true, startIndex, pageSize }
61-
})
24+
refreshVariables: (newExecutionCount?: number): CommonAction<IRefreshVariablesRequest> =>
25+
createIncomingActionWithPayload(CommonActionType.REFRESH_VARIABLES, { newExecutionCount }),
26+
restartKernel: (): CommonAction => createIncomingAction(CommonActionType.RESTART_KERNEL),
27+
interruptKernel: (): CommonAction => createIncomingAction(CommonActionType.INTERRUPT_KERNEL),
28+
deleteAllCells: (): CommonAction => createIncomingAction(InteractiveWindowMessages.DeleteAllCells),
29+
deleteCell: (cellId: string): CommonAction<ICellAction> => createIncomingActionWithPayload(InteractiveWindowMessages.DeleteCell, { cellId }),
30+
undo: (): CommonAction => createIncomingAction(InteractiveWindowMessages.Undo),
31+
redo: (): CommonAction => createIncomingAction(InteractiveWindowMessages.Redo),
32+
linkClick: (href: string): CommonAction<ILinkClickAction> => createIncomingActionWithPayload(CommonActionType.LINK_CLICK, { href }),
33+
showPlot: (imageHtml: string): CommonAction<string> => createIncomingActionWithPayload(InteractiveWindowMessages.ShowPlot, imageHtml),
34+
toggleInputBlock: (cellId: string): CommonAction<ICellAction> => createIncomingActionWithPayload(CommonActionType.TOGGLE_INPUT_BLOCK, { cellId }),
35+
gotoCell: (cellId: string): CommonAction<ICellAction> => createIncomingActionWithPayload(CommonActionType.GOTO_CELL, { cellId }),
36+
copyCellCode: (cellId: string): CommonAction<ICellAction> => createIncomingActionWithPayload(CommonActionType.COPY_CELL_CODE, { cellId }),
37+
gatherCell: (cellId: string): CommonAction<ICellAction> => createIncomingActionWithPayload(CommonActionType.GATHER_CELL, { cellId }),
38+
clickCell: (cellId: string): CommonAction<ICellAction> => createIncomingActionWithPayload(CommonActionType.CLICK_CELL, { cellId }),
39+
doubleClickCell: (cellId: string): CommonAction<ICellAction> => createIncomingActionWithPayload(CommonActionType.DOUBLE_CLICK_CELL, { cellId }),
40+
editCell: (cellId: string, changes: monacoEditor.editor.IModelContentChange[], modelId: string, code: string): CommonAction<IEditCellAction> =>
41+
createIncomingActionWithPayload(CommonActionType.EDIT_CELL, { cellId, changes, modelId, code }),
42+
submitInput: (code: string, cellId: string): CommonAction<ICodeAction> => createIncomingActionWithPayload(CommonActionType.SUBMIT_INPUT, { code, cellId }),
43+
toggleVariableExplorer: (): CommonAction => createIncomingAction(CommonActionType.TOGGLE_VARIABLE_EXPLORER),
44+
expandAll: (): CommonAction => createIncomingAction(InteractiveWindowMessages.ExpandAll),
45+
collapseAll: (): CommonAction => createIncomingAction(InteractiveWindowMessages.CollapseAll),
46+
export: (): CommonAction => createIncomingAction(CommonActionType.EXPORT),
47+
showDataViewer: (variable: IJupyterVariable, columnSize: number): CommonAction<IShowDataViewerAction> =>
48+
createIncomingActionWithPayload(CommonActionType.SHOW_DATA_VIEWER, { variable, columnSize }),
49+
editorLoaded: (): CommonAction => createIncomingAction(CommonActionType.EDITOR_LOADED),
50+
scroll: (isAtBottom: boolean): CommonAction<IScrollAction> => createIncomingActionWithPayload(CommonActionType.SCROLL, { isAtBottom }),
51+
unfocus: (cellId: string | undefined): CommonAction<ICellAction> => createIncomingActionWithPayload(CommonActionType.UNFOCUS_CELL, { cellId }),
52+
codeCreated: (cellId: string | undefined, modelId: string): CommonAction<ICodeCreatedAction> =>
53+
createIncomingActionWithPayload(CommonActionType.CODE_CREATED, { cellId, modelId }),
54+
editorUnmounted: (): CommonAction => createIncomingAction(CommonActionType.UNMOUNT),
55+
selectKernel: (): CommonAction => createIncomingAction(InteractiveWindowMessages.SelectKernel),
56+
selectServer: (): CommonAction => createIncomingAction(CommonActionType.SELECT_SERVER),
57+
getVariableData: (newExecutionCount: number, startIndex: number = 0, pageSize: number = 100): CommonAction<IJupyterVariablesRequest> =>
58+
createIncomingActionWithPayload(CommonActionType.GET_VARIABLE_DATA, { executionCount: newExecutionCount, sortColumn: 'name', sortAscending: true, startIndex, pageSize })
6259
};

0 commit comments

Comments
 (0)