@marimo-team/islands 0.21.2-dev57 → 0.21.2-dev59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ConnectedDataExplorerComponent-D0GoOd_c.js → ConnectedDataExplorerComponent-DrWDbHRV.js} +1 -1
- package/dist/main.js +243 -16
- package/dist/{spec-Bfvf9Hre.js → spec-oVDndBz4.js} +25 -16
- package/package.json +1 -1
- package/src/__mocks__/requests.ts +1 -0
- package/src/components/editor/file-tree/file-explorer.tsx +16 -2
- package/src/components/editor/file-tree/file-viewer.tsx +17 -3
- package/src/core/cells/__tests__/apply-transaction.test.ts +279 -0
- package/src/core/cells/__tests__/cells.test.ts +6 -0
- package/src/core/cells/__tests__/document-changes.test.ts +575 -0
- package/src/core/cells/__tests__/document-roundtrip.test.ts +376 -0
- package/src/core/cells/cells.ts +28 -3
- package/src/core/cells/document-changes.ts +644 -0
- package/src/core/islands/bridge.ts +1 -0
- package/src/core/islands/main.ts +2 -0
- package/src/core/network/requests-lazy.ts +1 -0
- package/src/core/network/requests-network.ts +9 -0
- package/src/core/network/requests-static.ts +1 -0
- package/src/core/network/requests-toasting.tsx +1 -0
- package/src/core/network/types.ts +5 -0
- package/src/core/wasm/bridge.ts +1 -0
- package/src/core/websocket/useMarimoKernelConnection.tsx +19 -1
- package/src/utils/createReducer.ts +26 -11
|
@@ -80,6 +80,8 @@ export interface SetCellConfigRequest {
|
|
|
80
80
|
export type UpdateUIElementRequest = schemas["UpdateUIElementRequest"];
|
|
81
81
|
export type ModelRequest = schemas["ModelRequest"];
|
|
82
82
|
export type UpdateCellIdsRequest = schemas["UpdateCellIdsRequest"];
|
|
83
|
+
export type NotebookDocumentTransactionRequest =
|
|
84
|
+
schemas["NotebookDocumentTransactionRequest"];
|
|
83
85
|
export type UpdateUserConfigRequest = schemas["UpdateUserConfigRequest"];
|
|
84
86
|
export type ShutdownSessionRequest = schemas["ShutdownSessionRequest"];
|
|
85
87
|
export type Snippet = schemas["Snippet"];
|
|
@@ -138,6 +140,9 @@ export interface EditRequests {
|
|
|
138
140
|
saveCellConfig: (request: SetCellConfigRequest) => Promise<null>;
|
|
139
141
|
sendRestart: () => Promise<null>;
|
|
140
142
|
syncCellIds: (request: UpdateCellIdsRequest) => Promise<null>;
|
|
143
|
+
sendDocumentTransaction: (
|
|
144
|
+
request: NotebookDocumentTransactionRequest,
|
|
145
|
+
) => Promise<null>;
|
|
141
146
|
sendInstallMissingPackages: (
|
|
142
147
|
request: InstallPackagesRequest,
|
|
143
148
|
) => Promise<null>;
|
package/src/core/wasm/bridge.ts
CHANGED
|
@@ -549,6 +549,7 @@ export class PyodideBridge implements RunRequests, EditRequests {
|
|
|
549
549
|
};
|
|
550
550
|
|
|
551
551
|
syncCellIds = () => Promise.resolve(null);
|
|
552
|
+
sendDocumentTransaction = () => Promise.resolve(null);
|
|
552
553
|
|
|
553
554
|
addPackage: EditRequests["addPackage"] = async (request) => {
|
|
554
555
|
return this.rpc.proxy.request.addPackage(request);
|
|
@@ -5,8 +5,12 @@ import { useRef } from "react";
|
|
|
5
5
|
import { useErrorBoundary } from "react-error-boundary";
|
|
6
6
|
import { toast } from "@/components/ui/use-toast";
|
|
7
7
|
import { getNotebook, useCellActions } from "@/core/cells/cells";
|
|
8
|
+
import { applyTransactionChanges } from "@/core/cells/document-changes";
|
|
8
9
|
import { AUTOCOMPLETER } from "@/core/codemirror/completion/Autocompleter";
|
|
9
|
-
import type {
|
|
10
|
+
import type {
|
|
11
|
+
NotificationMessageData,
|
|
12
|
+
NotificationPayload,
|
|
13
|
+
} from "@/core/kernel/messages";
|
|
10
14
|
import { useConnectionTransport } from "@/core/websocket/useWebSocket";
|
|
11
15
|
import { renderHTML } from "@/plugins/core/RenderHTML";
|
|
12
16
|
import {
|
|
@@ -93,6 +97,17 @@ export function useMarimoKernelConnection(opts: {
|
|
|
93
97
|
const { showBoundary } = useErrorBoundary();
|
|
94
98
|
|
|
95
99
|
const { handleCellMessage, setCellCodes, setCellIds } = useCellActions();
|
|
100
|
+
const actionsWithoutMiddleware = useCellActions({ skipMiddleware: true });
|
|
101
|
+
|
|
102
|
+
const handleDocumentTransaction = (
|
|
103
|
+
transaction: NotificationMessageData<"notebook-document-transaction">["transaction"],
|
|
104
|
+
) => {
|
|
105
|
+
applyTransactionChanges(
|
|
106
|
+
transaction.changes,
|
|
107
|
+
actionsWithoutMiddleware,
|
|
108
|
+
() => getNotebook().cellIds.inOrderIds,
|
|
109
|
+
);
|
|
110
|
+
};
|
|
96
111
|
const { addCellNotification } = useRunsActions();
|
|
97
112
|
const setKernelState = useSetAtom(kernelStateAtom);
|
|
98
113
|
const setAppConfig = useSetAppConfig();
|
|
@@ -321,6 +336,9 @@ export function useMarimoKernelConnection(opts: {
|
|
|
321
336
|
case "update-cell-ids":
|
|
322
337
|
setCellIds({ cellIds: msg.data.cell_ids });
|
|
323
338
|
return;
|
|
339
|
+
case "notebook-document-transaction":
|
|
340
|
+
handleDocumentTransaction(msg.data.transaction);
|
|
341
|
+
return;
|
|
324
342
|
default:
|
|
325
343
|
logNever(msg.data);
|
|
326
344
|
}
|
|
@@ -27,6 +27,13 @@ type ReducerActions<RH extends ReducerHandlers<any>> = {
|
|
|
27
27
|
: never;
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
+
/** Helper for typing middleware that receives dispatched actions. */
|
|
31
|
+
export type DispatchedActionOf<T> = {
|
|
32
|
+
[Key in keyof T]: T[Key] extends (payload: infer P) => any
|
|
33
|
+
? { type: Key; payload: P }
|
|
34
|
+
: never;
|
|
35
|
+
}[keyof T & string];
|
|
36
|
+
|
|
30
37
|
export interface ReducerCreatorResult<
|
|
31
38
|
State,
|
|
32
39
|
RH extends ReducerHandlers<State>,
|
|
@@ -80,21 +87,20 @@ export function createReducerAndAtoms<
|
|
|
80
87
|
State,
|
|
81
88
|
RH extends ReducerHandlers<NoInfer<State>>,
|
|
82
89
|
>(initialState: () => State, reducers: RH, middleware?: Middleware<State>[]) {
|
|
90
|
+
const allMiddleware = [...(middleware ?? [])];
|
|
91
|
+
const addMiddleware = (mw: Middleware<State>) => {
|
|
92
|
+
allMiddleware.push(mw);
|
|
93
|
+
};
|
|
83
94
|
const { reducer, createActions } = createReducer(initialState, reducers);
|
|
84
95
|
|
|
85
96
|
const reducerWithMiddleware = (state: State, action: ReducerAction<any>) => {
|
|
86
97
|
try {
|
|
87
98
|
const newState = reducer(state, action);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
Logger.error(
|
|
94
|
-
`Error in middleware for action ${action.type}:`,
|
|
95
|
-
error,
|
|
96
|
-
);
|
|
97
|
-
}
|
|
99
|
+
for (const mw of allMiddleware) {
|
|
100
|
+
try {
|
|
101
|
+
mw(state, newState, action);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
Logger.error(`Error in middleware for action ${action.type}:`, error);
|
|
98
104
|
}
|
|
99
105
|
}
|
|
100
106
|
return newState;
|
|
@@ -108,9 +114,17 @@ export function createReducerAndAtoms<
|
|
|
108
114
|
// map of SetAtom => Actions
|
|
109
115
|
const actionsMap = new WeakMap();
|
|
110
116
|
|
|
111
|
-
function useActions(
|
|
117
|
+
function useActions(
|
|
118
|
+
options: { skipMiddleware?: boolean } = {},
|
|
119
|
+
): ReducerActions<RH> {
|
|
112
120
|
const setState = useSetAtom(valueAtom);
|
|
113
121
|
|
|
122
|
+
if (options.skipMiddleware === true) {
|
|
123
|
+
return createActions((action: ReducerAction<any>) => {
|
|
124
|
+
setState((state: State) => reducer(state, action));
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
114
128
|
if (!actionsMap.has(setState)) {
|
|
115
129
|
actionsMap.set(
|
|
116
130
|
setState,
|
|
@@ -126,6 +140,7 @@ export function createReducerAndAtoms<
|
|
|
126
140
|
|
|
127
141
|
return {
|
|
128
142
|
reducer: reducerWithMiddleware,
|
|
143
|
+
addMiddleware,
|
|
129
144
|
createActions,
|
|
130
145
|
valueAtom,
|
|
131
146
|
useActions,
|