@marimo-team/islands 0.22.4-dev2 → 0.22.4-dev6
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/{chat-ui-Cel1kBfc.js → chat-ui-BlEsENC-.js} +1 -1
- package/dist/main.js +6 -5
- package/dist/{process-output-DC1TOnIl.js → process-output-D1b_hWPJ.js} +10 -1
- package/package.json +1 -1
- package/src/core/cells/__tests__/apply-transaction.test.ts +28 -0
- package/src/core/cells/cells.ts +13 -1
- package/src/plugins/impl/anywidget/AnyWidgetPlugin.tsx +8 -6
- package/src/plugins/impl/anywidget/__tests__/AnyWidgetPlugin.test.tsx +25 -0
|
@@ -5,7 +5,7 @@ import { s as __toESM, t as __commonJSMin } from "./chunk-BNovOVIE.js";
|
|
|
5
5
|
import { t as require_react } from "./react-Bs6Z0kvn.js";
|
|
6
6
|
import { t as require_compiler_runtime } from "./compiler-runtime-B_OLMU9S.js";
|
|
7
7
|
import { r as toast } from "./copy-B7781WJ3.js";
|
|
8
|
-
import { A as MarimoIncomingMessageEvent, At as moveToEndOfEditor, Bn as CircleX, C as contextToXml, D as AccordionContent, Dn as Wrench, Dt as createVariableInfoElement, E as Accordion, Fn as File$1, Gt as dataSourceConnectionsAtom, I as ChatBubbleIcon, Jt as getRequestClient, Kt as getTableType, Lt as jotaiJsonStorage, Mn as LoaderCircle, O as AccordionItem, On as Trash2, Pn as Info, Q as cellErrorsAtom, Qt as singleFacet, Rt as variablesAtom, S as Sections, T as AIContextRegistry, U as deserializeBlob, W as base64ToDataURL, Wt as allTablesAtom, Z as renderHTML, a as toPng, bt as displayCellName, cn as CellOutputId, d as Spinner, f as Popover, g as isOutputEmpty, h as PopoverTrigger, k as AccordionTrigger, m as PopoverContent, n as blobToString, nt as notebookAtom, o as MarkdownRenderer, rn as ZodLocalStorage, t as processOutput, w as AIContextProvider, x as Boosts, xn as Anchor2, y as DatasourceContextProvider, yn as atomWithStorage, zt as PluralWord } from "./process-output-
|
|
8
|
+
import { A as MarimoIncomingMessageEvent, At as moveToEndOfEditor, Bn as CircleX, C as contextToXml, D as AccordionContent, Dn as Wrench, Dt as createVariableInfoElement, E as Accordion, Fn as File$1, Gt as dataSourceConnectionsAtom, I as ChatBubbleIcon, Jt as getRequestClient, Kt as getTableType, Lt as jotaiJsonStorage, Mn as LoaderCircle, O as AccordionItem, On as Trash2, Pn as Info, Q as cellErrorsAtom, Qt as singleFacet, Rt as variablesAtom, S as Sections, T as AIContextRegistry, U as deserializeBlob, W as base64ToDataURL, Wt as allTablesAtom, Z as renderHTML, a as toPng, bt as displayCellName, cn as CellOutputId, d as Spinner, f as Popover, g as isOutputEmpty, h as PopoverTrigger, k as AccordionTrigger, m as PopoverContent, n as blobToString, nt as notebookAtom, o as MarkdownRenderer, rn as ZodLocalStorage, t as processOutput, w as AIContextProvider, x as Boosts, xn as Anchor2, y as DatasourceContextProvider, yn as atomWithStorage, zt as PluralWord } from "./process-output-D1b_hWPJ.js";
|
|
9
9
|
import "./chunk-5FQGJX7Z-C428iZBW.js";
|
|
10
10
|
import { l as createLucideIcon } from "./dist-D_UjpfOY.js";
|
|
11
11
|
import { C as logNever, I as X, n as Strings, t as Label } from "./label-DbZGAoCH.js";
|
package/dist/main.js
CHANGED
|
@@ -21,7 +21,7 @@ import { a as __toCommonJS, n as __esmMin, r as __export, s as __toESM, t as __c
|
|
|
21
21
|
import { t as require_react } from "./react-Bs6Z0kvn.js";
|
|
22
22
|
import { t as require_compiler_runtime } from "./compiler-runtime-B_OLMU9S.js";
|
|
23
23
|
import { n as Copy, r as toast, t as copyToClipboard } from "./copy-B7781WJ3.js";
|
|
24
|
-
import { $ as createActions, $t as elementContainsMarimoCellFile, A as MarimoIncomingMessageEvent, An as PaintRoller, B as DotFilledIcon, Bn as CircleX, Bt as PluralWords, Cn as Content2$1, Ct as normalizeName, D as AccordionContent, Dn as Wrench, E as Accordion, En as Trigger2, Et as MarkdownLanguageAdapter, F as BorderAllIcon, Fn as File, Ft as repl, G as base64ToDataView, H as PinRightIcon, Hn as Braces, Ht as getDataTypeColor, In as FileText, It as adaptForLocalStorage, J as extractBase64FromDataURL, Jt as getRequestClient, K as base64ToUint8Array, L as CheckIcon, Ln as Eye, Lt as jotaiJsonStorage, M as MarimoValueReadyEvent, Mn as LoaderCircle, Mt as DeferredRequestRegistry, N as MarimoValueUpdateEvent, Nn as Layers, Nt as generateUUID, O as AccordionItem, On as Trash2, Ot as PathBuilder, P as createInputEvent, Pn as Info, Pt as useChromeActions, R as ChevronDownIcon, Rn as Database, Sn as Close$1, St as isInternalCellName, Tn as Root2$4, Tt as customPythonLanguageSupport, U as deserializeBlob, Un as esm_default$1, Ut as require_client, V as PinLeftIcon, Vn as CircleAlert, Vt as DATA_TYPE_ICON, Wn as import_lib, X as safeExtractSetUIElementMessageBuffers, Xt as useRequestClient, Y as isDataURLString, Yt as requestClientAtom, Z as renderHTML, Zt as isUninstantiated, _ as useExpandedConsoleOutput, _n as jsonToTSV, _t as headingToIdentifier, a as toPng, an as parseAttrValue, at as useCellActions, b as getDatasourceContext, bn as selectAtom, bt as displayCellName, c as useCellFocusActions, cn as CellOutputId, ct as createCell, d as Spinner, dn as UIElementId, dt as initialModeAtom, en as extractAllTracebackInfo, et as getCellEditorView, f as Popover$1, fn as findCellId, ft as kioskModeAtom, g as isOutputEmpty, gn as jsonToMarkdown, gt as isErrorMime, h as PopoverTrigger, hn as jsonParseWithSpecialChar, ht as outputIsStale, i as PythonIcon, in as filenameAtom, it as reducer, j as MarimoValueInputEvent, jn as NotebookPen, jt as goToCellLine, k as AccordionTrigger, kn as Table2, kt as Paths, l as useLastFocusedCellId, ln as HTMLCellId, lt as AnsiUp, m as PopoverContent, mn as RANDOM_ID_ATTR, mt as outputIsLoading, n as blobToString, nn as NotebookScopedLocalStorage, nt as notebookAtom, o as MarkdownRenderer, on as parseDataset, ot as useCellIds, p as PopoverClose$1, pn as OBJECT_ID_ATTR, pt as viewStateAtom, q as dataViewToBase64, qt as convertStatsName, r as filesToBase64, rt as notebookOutline, s as LazyAnyLanguageCodeMirror, sn as parseInitialValue, st as useCellNames, t as processOutput, tn as getTracebackInfo, tt as getCellNames, u as maybeAddAltairImport, un as SCRATCH_CELL_ID, ut as getInitialAppMode, v as useExpandedOutput, vn as atomWithReducer, vt as DATA_CELL_ID, wn as Item$1, wt as Checkbox, xt as getValidName, yn as atomWithStorage, yt as getCellDomProps, z as ChevronRightIcon, zn as Columns2, zt as PluralWord, __tla as __tla_0 } from "./process-output-
|
|
24
|
+
import { $ as createActions, $t as elementContainsMarimoCellFile, A as MarimoIncomingMessageEvent, An as PaintRoller, B as DotFilledIcon, Bn as CircleX, Bt as PluralWords, Cn as Content2$1, Ct as normalizeName, D as AccordionContent, Dn as Wrench, E as Accordion, En as Trigger2, Et as MarkdownLanguageAdapter, F as BorderAllIcon, Fn as File, Ft as repl, G as base64ToDataView, H as PinRightIcon, Hn as Braces, Ht as getDataTypeColor, In as FileText, It as adaptForLocalStorage, J as extractBase64FromDataURL, Jt as getRequestClient, K as base64ToUint8Array, L as CheckIcon, Ln as Eye, Lt as jotaiJsonStorage, M as MarimoValueReadyEvent, Mn as LoaderCircle, Mt as DeferredRequestRegistry, N as MarimoValueUpdateEvent, Nn as Layers, Nt as generateUUID, O as AccordionItem, On as Trash2, Ot as PathBuilder, P as createInputEvent, Pn as Info, Pt as useChromeActions, R as ChevronDownIcon, Rn as Database, Sn as Close$1, St as isInternalCellName, Tn as Root2$4, Tt as customPythonLanguageSupport, U as deserializeBlob, Un as esm_default$1, Ut as require_client, V as PinLeftIcon, Vn as CircleAlert, Vt as DATA_TYPE_ICON, Wn as import_lib, X as safeExtractSetUIElementMessageBuffers, Xt as useRequestClient, Y as isDataURLString, Yt as requestClientAtom, Z as renderHTML, Zt as isUninstantiated, _ as useExpandedConsoleOutput, _n as jsonToTSV, _t as headingToIdentifier, a as toPng, an as parseAttrValue, at as useCellActions, b as getDatasourceContext, bn as selectAtom, bt as displayCellName, c as useCellFocusActions, cn as CellOutputId, ct as createCell, d as Spinner, dn as UIElementId, dt as initialModeAtom, en as extractAllTracebackInfo, et as getCellEditorView, f as Popover$1, fn as findCellId, ft as kioskModeAtom, g as isOutputEmpty, gn as jsonToMarkdown, gt as isErrorMime, h as PopoverTrigger, hn as jsonParseWithSpecialChar, ht as outputIsStale, i as PythonIcon, in as filenameAtom, it as reducer, j as MarimoValueInputEvent, jn as NotebookPen, jt as goToCellLine, k as AccordionTrigger, kn as Table2, kt as Paths, l as useLastFocusedCellId, ln as HTMLCellId, lt as AnsiUp, m as PopoverContent, mn as RANDOM_ID_ATTR, mt as outputIsLoading, n as blobToString, nn as NotebookScopedLocalStorage, nt as notebookAtom, o as MarkdownRenderer, on as parseDataset, ot as useCellIds, p as PopoverClose$1, pn as OBJECT_ID_ATTR, pt as viewStateAtom, q as dataViewToBase64, qt as convertStatsName, r as filesToBase64, rt as notebookOutline, s as LazyAnyLanguageCodeMirror, sn as parseInitialValue, st as useCellNames, t as processOutput, tn as getTracebackInfo, tt as getCellNames, u as maybeAddAltairImport, un as SCRATCH_CELL_ID, ut as getInitialAppMode, v as useExpandedOutput, vn as atomWithReducer, vt as DATA_CELL_ID, wn as Item$1, wt as Checkbox, xt as getValidName, yn as atomWithStorage, yt as getCellDomProps, z as ChevronRightIcon, zn as Columns2, zt as PluralWord, __tla as __tla_0 } from "./process-output-D1b_hWPJ.js";
|
|
25
25
|
import { __tla as __tla_1 } from "./chunk-5FQGJX7Z-C428iZBW.js";
|
|
26
26
|
import { l as createLucideIcon, o as useSize, s as Root$4 } from "./dist-D_UjpfOY.js";
|
|
27
27
|
import { A as $896ba0a80a8f4d36$export$85fd5fdf27bacc79, C as DEFAULT_COLOR_SCHEME, D as SCALE_TYPE_DESCRIPTIONS, E as EMPTY_VALUE$1, F as ListFilter, I as ChartPie, L as ChartColumn, M as $5a387cc49350e6db$export$722debc0e56fea39, N as Table$1, O as TIME_UNIT_DESCRIPTIONS, P as SquareFunction, S as DEFAULT_AGGREGATION, T as DEFAULT_TIME_UNIT, _ as AGGREGATION_TYPE_DESCRIPTIONS, a as AGGREGATION_FNS$1, b as COLOR_SCHEMES, c as COLOR_BY_FIELDS, d as NONE_VALUE, f as SELECTABLE_DATA_TYPES, g as TIME_UNITS, h as STRING_AGGREGATION_FNS, i as convertDataTypeToSelectable, j as $fb18d541ea1ad717$export$ad991b66133851cf, k as escapeFieldName, l as COMBINED_TIME_UNITS, m as SORT_TYPES, n as createSpecWithoutData, o as BIN_AGGREGATION, p as SINGLE_TIME_UNITS, r as isFieldSet, s as CHART_TYPES, t as augmentSpecWithData, u as ChartType, v as AGGREGATION_TYPE_ICON, w as DEFAULT_MAX_BINS_FACET, x as COUNT_FIELD, y as CHART_TYPE_ICON } from "./spec-CD7QaCV-.js";
|
|
@@ -36594,12 +36594,13 @@ ${E}`,
|
|
|
36594
36594
|
}
|
|
36595
36595
|
const AnyWidgetPlugin = createPlugin("marimo-anywidget").withData(object({
|
|
36596
36596
|
jsUrl: string(),
|
|
36597
|
-
jsHash: string()
|
|
36597
|
+
jsHash: string(),
|
|
36598
|
+
modelId: string().transform((e) => e)
|
|
36598
36599
|
})).withFunctions({}).renderer((e) => (0, import_jsx_runtime.jsx)(AnyWidgetSlot, {
|
|
36599
36600
|
...e
|
|
36600
36601
|
}));
|
|
36601
36602
|
var AnyWidgetSlot = (e) => {
|
|
36602
|
-
let r = (0, import_compiler_runtime$91.c)(14), { jsUrl: c, jsHash: d
|
|
36603
|
+
let r = (0, import_compiler_runtime$91.c)(14), { jsUrl: c, jsHash: d, modelId: f } = e.data, h = e.host, _;
|
|
36603
36604
|
r[0] !== d || r[1] !== c ? (_ = {
|
|
36604
36605
|
jsUrl: c,
|
|
36605
36606
|
jsHash: d
|
|
@@ -37075,7 +37076,7 @@ ${E}`,
|
|
|
37075
37076
|
};
|
|
37076
37077
|
}
|
|
37077
37078
|
};
|
|
37078
|
-
var LazyChatbot = import_react.lazy(() => import("./chat-ui-
|
|
37079
|
+
var LazyChatbot = import_react.lazy(() => import("./chat-ui-BlEsENC-.js").then((e) => ({
|
|
37079
37080
|
default: e.Chatbot
|
|
37080
37081
|
}))), messageSchema = array(object({
|
|
37081
37082
|
id: string(),
|
|
@@ -65540,7 +65541,7 @@ ${c}
|
|
|
65540
65541
|
return Logger.warn("Failed to get version from mount config"), null;
|
|
65541
65542
|
}
|
|
65542
65543
|
}
|
|
65543
|
-
const marimoVersionAtom = atom(getVersionFromMountConfig() || "0.22.4-
|
|
65544
|
+
const marimoVersionAtom = atom(getVersionFromMountConfig() || "0.22.4-dev6"), showCodeInRunModeAtom = atom(true);
|
|
65544
65545
|
atom(null);
|
|
65545
65546
|
var VIRTUAL_FILE_REGEX = /\/@file\/([^\s"&'/]+)\.([\dA-Za-z]+)/g, VirtualFileTracker = class e {
|
|
65546
65547
|
constructor() {
|
|
@@ -25437,7 +25437,16 @@ ${n.sqlString}
|
|
|
25437
25437
|
var _a2, _b2;
|
|
25438
25438
|
let n = t.cellId;
|
|
25439
25439
|
if (e.cellIds.hasOnlyOneId()) return e;
|
|
25440
|
-
let r
|
|
25440
|
+
let r;
|
|
25441
|
+
try {
|
|
25442
|
+
r = e.cellIds.findWithId(n);
|
|
25443
|
+
} catch (t2) {
|
|
25444
|
+
return Logger.warn("Skipping delete for missing cellId", {
|
|
25445
|
+
cellId: n,
|
|
25446
|
+
error: t2
|
|
25447
|
+
}), e;
|
|
25448
|
+
}
|
|
25449
|
+
let i = r.indexOfOrThrow(n), a = i === 0 ? 1 : i - 1, o = null;
|
|
25441
25450
|
r.length > 1 && (o = r.atOrThrow(a));
|
|
25442
25451
|
let s = (_b2 = (_a2 = e.cellHandles[n].current) == null ? void 0 : _a2.editorView) == null ? void 0 : _b2.state.toJSON({
|
|
25443
25452
|
history: historyField
|
package/package.json
CHANGED
|
@@ -267,6 +267,34 @@ describe("applyTransactionChanges edge cases", () => {
|
|
|
267
267
|
`);
|
|
268
268
|
});
|
|
269
269
|
|
|
270
|
+
it("delete-cell for nonexistent cell does not crash subsequent changes", () => {
|
|
271
|
+
setup("a", "b", "c");
|
|
272
|
+
const [, b] = state.cellIds.inOrderIds;
|
|
273
|
+
// Simulate the scenario from the bug report: a delete-cell for a cell ID
|
|
274
|
+
// that was never added to the frontend, followed by a create-cell and
|
|
275
|
+
// a set-code update. The delete should be silently skipped, and the rest
|
|
276
|
+
// of the transaction should still apply.
|
|
277
|
+
apply([
|
|
278
|
+
{ type: "delete-cell", cellId: cellId("nonexistent") },
|
|
279
|
+
{
|
|
280
|
+
type: "create-cell",
|
|
281
|
+
cellId: cellId("VrZA"),
|
|
282
|
+
code: "import altair as alt",
|
|
283
|
+
name: "",
|
|
284
|
+
config: { hide_code: true },
|
|
285
|
+
},
|
|
286
|
+
{ type: "set-code", cellId: b, code: "updated" },
|
|
287
|
+
]);
|
|
288
|
+
expect(pretty(state)).toMatchInlineSnapshot(`
|
|
289
|
+
"
|
|
290
|
+
0: 'a'
|
|
291
|
+
1: 'updated'
|
|
292
|
+
2: 'c'
|
|
293
|
+
VrZA: 'import altair as alt' [hide_code]
|
|
294
|
+
"
|
|
295
|
+
`);
|
|
296
|
+
});
|
|
297
|
+
|
|
270
298
|
it("empty changes is a no-op", () => {
|
|
271
299
|
setup("a", "b");
|
|
272
300
|
apply([]);
|
package/src/core/cells/cells.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { type Atom, atom, useAtom, useAtomValue } from "jotai";
|
|
|
6
6
|
import { atomFamily, selectAtom, splitAtom } from "jotai/utils";
|
|
7
7
|
import { createRef, type ReducerWithoutAction } from "react";
|
|
8
8
|
import type { CellHandle } from "@/components/editor/notebook-cell";
|
|
9
|
+
import type { CollapsibleTree } from "@/utils/id-tree";
|
|
9
10
|
import {
|
|
10
11
|
type CellColumnId,
|
|
11
12
|
type CellIndex,
|
|
@@ -578,7 +579,18 @@ const {
|
|
|
578
579
|
return state;
|
|
579
580
|
}
|
|
580
581
|
|
|
581
|
-
|
|
582
|
+
let column: CollapsibleTree<CellId>;
|
|
583
|
+
try {
|
|
584
|
+
column = state.cellIds.findWithId(cellId);
|
|
585
|
+
} catch (error) {
|
|
586
|
+
// Expected for kernel-only cells or out-of-order transactions.
|
|
587
|
+
Logger.warn("Skipping delete for missing cellId", {
|
|
588
|
+
cellId,
|
|
589
|
+
error,
|
|
590
|
+
});
|
|
591
|
+
return state;
|
|
592
|
+
}
|
|
593
|
+
|
|
582
594
|
const cellIndex = column.indexOfOrThrow(cellId);
|
|
583
595
|
const focusIndex = cellIndex === 0 ? 1 : cellIndex - 1;
|
|
584
596
|
let scrollKey: CellId | null = null;
|
|
@@ -21,17 +21,19 @@ import { BINDING_MANAGER, WIDGET_DEF_REGISTRY } from "./widget-binding";
|
|
|
21
21
|
interface Data {
|
|
22
22
|
jsUrl: string;
|
|
23
23
|
jsHash: string;
|
|
24
|
+
modelId: WidgetModelId;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
type AnyWidgetState = ModelState;
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
30
|
+
* Value payload sent by the frontend on state updates.
|
|
31
|
+
*
|
|
32
|
+
* The initial value from the backend is empty — `model_id` is passed
|
|
33
|
+
* via immutable data attributes (`args`) so it survives value overwrites.
|
|
32
34
|
*/
|
|
33
35
|
interface ModelIdRef {
|
|
34
|
-
model_id
|
|
36
|
+
model_id?: WidgetModelId;
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
export function useAnyWidgetModule(opts: { jsUrl: string; jsHash: string }) {
|
|
@@ -117,14 +119,14 @@ export const AnyWidgetPlugin = createPlugin<ModelIdRef>("marimo-anywidget")
|
|
|
117
119
|
z.object({
|
|
118
120
|
jsUrl: z.string(),
|
|
119
121
|
jsHash: z.string(),
|
|
122
|
+
modelId: z.string().transform((v) => v as WidgetModelId),
|
|
120
123
|
}),
|
|
121
124
|
)
|
|
122
125
|
.withFunctions({})
|
|
123
126
|
.renderer((props) => <AnyWidgetSlot {...props} />);
|
|
124
127
|
|
|
125
128
|
const AnyWidgetSlot = (props: IPluginProps<ModelIdRef, Data>) => {
|
|
126
|
-
const { jsUrl, jsHash } = props.data;
|
|
127
|
-
const { model_id: modelId } = props.value;
|
|
129
|
+
const { jsUrl, jsHash, modelId } = props.data;
|
|
128
130
|
const host = props.host as HTMLElementNotDerivedFromRef;
|
|
129
131
|
|
|
130
132
|
const { jsModule, error } = useAnyWidgetModule({ jsUrl, jsHash });
|
|
@@ -29,6 +29,7 @@ describe("LoadedSlot", () => {
|
|
|
29
29
|
data: {
|
|
30
30
|
jsUrl: "http://example.com/widget.js",
|
|
31
31
|
jsHash: "abc123",
|
|
32
|
+
modelId: modelId,
|
|
32
33
|
},
|
|
33
34
|
host: document.createElement(
|
|
34
35
|
"div",
|
|
@@ -67,6 +68,30 @@ describe("LoadedSlot", () => {
|
|
|
67
68
|
});
|
|
68
69
|
});
|
|
69
70
|
|
|
71
|
+
it("should not remount when value update drops model_id", async () => {
|
|
72
|
+
// Regression: when the frontend sends a state update (e.g. {zoom_level: 0}),
|
|
73
|
+
// it overwrites the UIElement value that originally held {model_id: "..."}.
|
|
74
|
+
// The key must stay stable because modelId comes from data, not value.
|
|
75
|
+
const { container, rerender } = render(<LoadedSlot {...mockProps} />);
|
|
76
|
+
|
|
77
|
+
await waitFor(() => {
|
|
78
|
+
expect(mockWidget.render).toHaveBeenCalledTimes(1);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const divBefore = container.querySelector("div");
|
|
82
|
+
|
|
83
|
+
// Simulate a value update that does NOT include model_id
|
|
84
|
+
// (this is what happens when the widget sends trait state)
|
|
85
|
+
rerender(<LoadedSlot {...mockProps} />);
|
|
86
|
+
|
|
87
|
+
await waitFor(() => {
|
|
88
|
+
// The div should be the same DOM node (no remount)
|
|
89
|
+
expect(container.querySelector("div")).toBe(divBefore);
|
|
90
|
+
// render should not be called again (no remount)
|
|
91
|
+
expect(mockWidget.render).toHaveBeenCalledTimes(1);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
70
95
|
it("should re-run widget when widget prop changes", async () => {
|
|
71
96
|
const { rerender } = render(<LoadedSlot {...mockProps} />);
|
|
72
97
|
|