@marimo-team/islands 0.22.4-dev2 → 0.22.4-dev3
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/main.js
CHANGED
|
@@ -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
|
|
@@ -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-dev3"), 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() {
|
package/package.json
CHANGED
|
@@ -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
|
|