@marimo-team/frontend 0.21.2-dev76 → 0.21.2-dev77

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/frontend",
3
- "version": "0.21.2-dev76",
3
+ "version": "0.21.2-dev77",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -51,10 +51,7 @@ function createEditor(code: string) {
51
51
  }
52
52
 
53
53
  /** Dispatch an action through the reducer and auto-create editor handles. */
54
- function dispatch(
55
- state: NotebookState,
56
- action: { type: string; payload: unknown },
57
- ): NotebookState {
54
+ function dispatch(state: NotebookState, action: CellAction): NotebookState {
58
55
  const next = reducer(state, action);
59
56
  for (const [cellIdString, handle] of Object.entries(next.cellHandles)) {
60
57
  const cid = cellIdString as CellId;
@@ -148,7 +148,7 @@ describe("RunsState Reducer", () => {
148
148
  run_id: runId,
149
149
  cell_id: testCellId,
150
150
  timestamp: runStartTimestamp + 5000,
151
- status: "success",
151
+ status: "idle",
152
152
  },
153
153
  code: "console.log('Hello World');",
154
154
  },
@@ -226,7 +226,8 @@ describe("RunsState Reducer", () => {
226
226
  status: "running",
227
227
  output: {
228
228
  channel: "stderr",
229
- text: "Error occurred",
229
+ data: "Error occurred",
230
+ mimetype: "text/plain",
230
231
  },
231
232
  },
232
233
  code: "console.log('Hello World');",
@@ -254,7 +255,8 @@ describe("RunsState Reducer", () => {
254
255
  status: "running",
255
256
  output: {
256
257
  channel: "marimo-error",
257
- text: "Error occurred",
258
+ data: "Error occurred",
259
+ mimetype: "text/plain",
258
260
  },
259
261
  },
260
262
  code: "console.log('Hello World');",
@@ -278,6 +280,8 @@ describe("RunsState Reducer", () => {
278
280
  timestamp,
279
281
  output: {
280
282
  channel: "marimo-error",
283
+ data: "",
284
+ mimetype: "text/plain",
281
285
  },
282
286
  },
283
287
  code: "console.log('Hello World');",
@@ -1425,7 +1425,6 @@ const {
1425
1425
  // We apply the middleware here (rather than inline in createReducerAndAtoms)
1426
1426
  // so that the document transaction middleware can import CellActions and
1427
1427
  // strictly type the dispatched actions without creating a circular dependency.
1428
- // @ts-expect-error - TODO: We should have better types for the middleware that are strict
1429
1428
  addMiddleware(documentTransactionMiddleware);
1430
1429
 
1431
1430
  function isCellCodeHidden(state: NotebookState, cellId: CellId): boolean {
@@ -133,7 +133,7 @@ describe("createReducerAndAtoms", () => {
133
133
  ]);
134
134
 
135
135
  const state = { count: 0 };
136
- const action = { type: "increment", payload: 5 };
136
+ const action = { type: "increment", payload: 5 } as const;
137
137
  reducer(state, action);
138
138
 
139
139
  expect(middleware).toHaveBeenCalledWith(state, { count: 5 }, action);
@@ -150,6 +150,7 @@ describe("createReducerAndAtoms", () => {
150
150
 
151
151
  const { reducer } = createReducerAndAtoms(initialState, reducers);
152
152
  const state = { count: 0 };
153
+ // @ts-expect-error - we are testing this
153
154
  const newState = reducer(state, { type: "nonexistent", payload: null });
154
155
 
155
156
  expect(newState).toBe(state);
@@ -7,12 +7,7 @@ import { Logger } from "@/utils/Logger";
7
7
 
8
8
  export type NoInfer<T> = [T][T extends any ? 0 : never];
9
9
 
10
- interface ReducerAction<T> {
11
- type: string;
12
- payload: T;
13
- }
14
-
15
- type Dispatch = (action: ReducerAction<any>) => void;
10
+ type Dispatch<RH> = (action: ReducerActionOf<RH>) => void;
16
11
  type IfUnknown<T, Y, N> = unknown extends T ? Y : N;
17
12
 
18
13
  type ReducerHandler<State, Payload> = (state: State, payload: Payload) => State;
@@ -34,6 +29,12 @@ export type DispatchedActionOf<T> = {
34
29
  : never;
35
30
  }[keyof T & string];
36
31
 
32
+ type ReducerActionOf<RH> = {
33
+ [Type in keyof RH]: RH[Type] extends ReducerHandler<any, infer Payload>
34
+ ? { type: Type; payload: Payload }
35
+ : never;
36
+ }[keyof RH & string];
37
+
37
38
  export interface ReducerCreatorResult<
38
39
  State,
39
40
  RH extends ReducerHandlers<State>,
@@ -45,7 +46,7 @@ export interface ReducerCreatorResult<
45
46
  /**
46
47
  * Given a dispatch function, returns an object containing all the actions.
47
48
  */
48
- createActions: (dispatch: Dispatch) => ReducerActions<RH>;
49
+ createActions: (dispatch: Dispatch<RH>) => ReducerActions<RH>;
49
50
  }
50
51
 
51
52
  /**
@@ -56,7 +57,7 @@ export function createReducer<
56
57
  RH extends ReducerHandlers<NoInfer<State>>,
57
58
  >(initialState: () => State, reducers: RH): ReducerCreatorResult<State, RH> {
58
59
  return {
59
- reducer: (state, action: ReducerAction<RH>) => {
60
+ reducer: (state, action: ReducerActionOf<RH>) => {
60
61
  state = state || initialState();
61
62
  if (action.type in reducers) {
62
63
  return reducers[action.type](state, action.payload);
@@ -65,11 +66,11 @@ export function createReducer<
65
66
  Logger.error(`Action type ${action.type} is not defined in reducers.`);
66
67
  return state;
67
68
  },
68
- createActions: (dispatch: Dispatch) => {
69
+ createActions: (dispatch: Dispatch<RH>) => {
69
70
  const actions = {} as ReducerActions<RH>;
70
71
  for (const type in reducers) {
71
72
  (actions as any)[type] = (payload: any) => {
72
- dispatch({ type, payload });
73
+ dispatch({ type, payload } as any);
73
74
  };
74
75
  }
75
76
  return actions;
@@ -77,23 +78,27 @@ export function createReducer<
77
78
  };
78
79
  }
79
80
 
80
- type Middleware<State> = (
81
+ type Middleware<State, RH> = (
81
82
  prevState: State,
82
83
  newState: State,
83
- action: ReducerAction<any>,
84
+ action: ReducerActionOf<RH>,
84
85
  ) => void;
85
86
 
86
87
  export function createReducerAndAtoms<
87
88
  State,
88
89
  RH extends ReducerHandlers<NoInfer<State>>,
89
- >(initialState: () => State, reducers: RH, middleware?: Middleware<State>[]) {
90
+ >(
91
+ initialState: () => State,
92
+ reducers: RH,
93
+ middleware?: Middleware<State, NoInfer<RH>>[],
94
+ ) {
90
95
  const allMiddleware = [...(middleware ?? [])];
91
- const addMiddleware = (mw: Middleware<State>) => {
96
+ const addMiddleware = (mw: Middleware<State, RH>) => {
92
97
  allMiddleware.push(mw);
93
98
  };
94
99
  const { reducer, createActions } = createReducer(initialState, reducers);
95
100
 
96
- const reducerWithMiddleware = (state: State, action: ReducerAction<any>) => {
101
+ const reducerWithMiddleware = (state: State, action: ReducerActionOf<RH>) => {
97
102
  try {
98
103
  const newState = reducer(state, action);
99
104
  for (const mw of allMiddleware) {
@@ -120,7 +125,7 @@ export function createReducerAndAtoms<
120
125
  const setState = useSetAtom(valueAtom);
121
126
 
122
127
  if (options.skipMiddleware === true) {
123
- return createActions((action: ReducerAction<any>) => {
128
+ return createActions((action: ReducerActionOf<RH>) => {
124
129
  setState((state: State) => reducer(state, action));
125
130
  });
126
131
  }
@@ -128,7 +133,7 @@ export function createReducerAndAtoms<
128
133
  if (!actionsMap.has(setState)) {
129
134
  actionsMap.set(
130
135
  setState,
131
- createActions((action: ReducerAction<any>) => {
136
+ createActions((action: ReducerActionOf<RH>) => {
132
137
  setState((state: State) => reducerWithMiddleware(state, action));
133
138
  }),
134
139
  );