@marimo-team/frontend 0.21.2-dev37 → 0.21.2-dev40

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.
Files changed (141) hide show
  1. package/dist/assets/{CellStatus-DYdGvia_.js → CellStatus-IHJk0CT8.js} +1 -1
  2. package/dist/assets/{JsonOutput-CN6rPeEV.js → JsonOutput-BIbkaOuk.js} +9 -9
  3. package/dist/assets/{MarimoErrorOutput-BhfAlCn4.js → MarimoErrorOutput-hYOXA8Ml.js} +5 -5
  4. package/dist/assets/{RenderHTML-BS4HOKgA.js → RenderHTML-DduaBOBv.js} +1 -1
  5. package/dist/assets/{add-cell-with-ai-pEba6oGB.js → add-cell-with-ai-Cbktc1B0.js} +9 -9
  6. package/dist/assets/{add-connection-dialog-9odisycO.js → add-connection-dialog-BewAq3li.js} +23 -23
  7. package/dist/assets/{agent-panel-BSEF-vxf.js → agent-panel-CtAqa-P9.js} +5 -5
  8. package/dist/assets/{ai-model-dropdown-CBQHQst1.js → ai-model-dropdown-DgMZ5T_L.js} +3 -3
  9. package/dist/assets/{app-config-button-XC0eJuj1.js → app-config-button-BLGBmcfT.js} +1 -1
  10. package/dist/assets/{azure-Cl-hv4CT.js → azure-BeB26UeM.js} +1 -1
  11. package/dist/assets/{cell-editor-CtnuCOtA.js → cell-editor-Ti3F6axu.js} +12 -13
  12. package/dist/assets/{cell-link-D8ZUYcpP.js → cell-link-BEnixmCb.js} +1 -1
  13. package/dist/assets/{cells-DZyIQGyJ.js → cells-DqKJsMUm.js} +79 -78
  14. package/dist/assets/{chat-display-CvRHSFG6.js → chat-display-B0hV2K6L.js} +1 -1
  15. package/dist/assets/{chat-panel-BAGhr_FT.js → chat-panel-CNGIGWIs.js} +2 -2
  16. package/dist/assets/{column-preview-BuB6sz5V.js → column-preview-CVqBaB8R.js} +1 -1
  17. package/dist/assets/{command-DxWyVVPx.js → command-DpusMohg.js} +1 -1
  18. package/dist/assets/{command-palette-BjbqAF2r.js → command-palette-BfuIslSf.js} +1 -1
  19. package/dist/assets/{common-DJx7lN8H.js → common-CYWtZYKm.js} +1 -1
  20. package/dist/assets/{components-ENebof0d.js → components-C4dDqD7U.js} +1 -1
  21. package/dist/assets/{components-DSj55gbq.js → components-DZQ7ndNS.js} +1 -1
  22. package/dist/assets/{context-aware-panel-C4GJI0g0.js → context-aware-panel-DEVrXLoa.js} +3 -3
  23. package/dist/assets/{datasource-Be25L0nm.js → datasource-Bo8w993m.js} +2 -2
  24. package/dist/assets/{dependency-graph-panel-DwIVdeIJ.js → dependency-graph-panel-u9oPy09H.js} +4 -4
  25. package/dist/assets/{documentation-panel-78VOc9_O.js → documentation-panel-BQRmNRb_.js} +1 -1
  26. package/dist/assets/{download-BlNsDzA2.js → download-DtyAt8iO.js} +1 -1
  27. package/dist/assets/{edit-page-vExGqsee.js → edit-page-Cqvk7zWH.js} +7 -7
  28. package/dist/assets/{error-panel-D8Yl4tpB.js → error-panel-DclemF57.js} +1 -1
  29. package/dist/assets/{file-explorer-panel-CbIYi1SW.js → file-explorer-panel-D706RRJ-.js} +3 -3
  30. package/dist/assets/{file-icons-zgA9qh-d.js → file-icons-D4HcGlr_.js} +1 -1
  31. package/dist/assets/{floating-outline-vyq-JnTK.js → floating-outline-B86gVj23.js} +1 -1
  32. package/dist/assets/{focus-Cnr-VB8o.js → focus-B85PAbhR.js} +1 -1
  33. package/dist/assets/{form-LO1BJ8WB.js → form--K3o18rQ.js} +2 -2
  34. package/dist/assets/{globals-3fE4PBWj.js → globals-C_t1YYpc.js} +1 -1
  35. package/dist/assets/{home-page-DFcaf-s1.js → home-page-C5LO1JXE.js} +1 -1
  36. package/dist/assets/{hooks-NxoY-x2K.js → hooks-W-qT5c6l.js} +1 -1
  37. package/dist/assets/{html-to-image-DDWA96Ex.js → html-to-image-CoMmxXBd.js} +1 -1
  38. package/dist/assets/{index-OH-GH0bF.js → index-BSzIstPK.js} +14 -14
  39. package/dist/assets/{kiosk-mode-D4FbpWVp.js → kiosk-mode-zv0zIGqw.js} +1 -1
  40. package/dist/assets/{layout-qNHT912R.js → layout-C_JVKYrz.js} +3 -3
  41. package/dist/assets/{logs-panel-14Cp2UUn.js → logs-panel-DowtOCA5.js} +1 -1
  42. package/dist/assets/{markdown-renderer-CH1ffrUG.js → markdown-renderer-CNaYgTOF.js} +1 -1
  43. package/dist/assets/{mode-OBdgd6Zz.js → mode-Bn_XF6AW.js} +1 -1
  44. package/dist/assets/{name-cell-input-BmkGdvnh.js → name-cell-input-CVt9kv6F.js} +1 -1
  45. package/dist/assets/{outline-panel-Bn1SN1eu.js → outline-panel-ClI23gcy.js} +1 -1
  46. package/dist/assets/{packages-panel-Cyb4BUmM.js → packages-panel-BW2m-sNe.js} +1 -1
  47. package/dist/assets/{panels-DfEUpHpA.js → panels-B2DAaT1E.js} +1 -1
  48. package/dist/assets/{process-output-CC4VhdkC.js → process-output-BewZuQwI.js} +1 -1
  49. package/dist/assets/{readonly-python-code-Cq9EKL61.js → readonly-python-code-BgTK_w0H.js} +1 -1
  50. package/dist/assets/{run-page-Df9bi2J7.js → run-page-DMpRvHgf.js} +1 -1
  51. package/dist/assets/{scratchpad-panel-vKbONRfT.js → scratchpad-panel-ClDi2sdV.js} +1 -1
  52. package/dist/assets/{session-panel-DPoC2CoL.js → session-panel-C-RbWN-G.js} +1 -1
  53. package/dist/assets/{snippets-panel-D7W6PE7E.js → snippets-panel-DCdeI2hB.js} +1 -1
  54. package/dist/assets/{state-Br7baqTT.js → state-CJ2HIW-e.js} +1 -1
  55. package/dist/assets/{switch-Cds8TleW.js → switch-O_7alg7G.js} +1 -1
  56. package/dist/assets/tracing-BxcUfhUv.js +1 -0
  57. package/dist/assets/{tracing-panel-BpKr5n4H.js → tracing-panel-DK4YfdoZ.js} +2 -2
  58. package/dist/assets/{useAddCell-XcxY_cZw.js → useAddCell-BpBkEpP6.js} +1 -1
  59. package/dist/assets/{useBoolean-0C18DvVA.js → useBoolean-Cb23qnhy.js} +1 -1
  60. package/dist/assets/{useCellActionButton-DFNSBzoc.js → useCellActionButton-fJ6SGX-Z.js} +1 -1
  61. package/dist/assets/{useDeleteCell-DLdqnODD.js → useDeleteCell-B4nKRnTM.js} +1 -1
  62. package/dist/assets/{useDependencyPanelTab-_E0t8nfy.js → useDependencyPanelTab-BUjZxWnG.js} +1 -1
  63. package/dist/assets/{useNotebookActions-DlbYUPWD.js → useNotebookActions-CooxVonM.js} +1 -1
  64. package/dist/assets/{useRunCells-YR_s_yuq.js → useRunCells-D5wCIJdU.js} +1 -1
  65. package/dist/assets/{useSplitCell-BNkvoKCq.js → useSplitCell-D8kqiCTS.js} +1 -1
  66. package/dist/index.html +32 -32
  67. package/package.json +1 -1
  68. package/src/__mocks__/notebook.ts +9 -9
  69. package/src/__tests__/branded.ts +20 -0
  70. package/src/components/data-table/charts/__tests__/storage.test.ts +7 -7
  71. package/src/components/editor/__tests__/data-attributes.test.tsx +8 -8
  72. package/src/components/editor/ai/__tests__/completion-utils.test.ts +15 -15
  73. package/src/components/editor/navigation/__tests__/clipboard.test.ts +2 -2
  74. package/src/components/editor/navigation/__tests__/selection.test.ts +7 -6
  75. package/src/components/editor/navigation/__tests__/state.test.ts +8 -7
  76. package/src/components/editor/output/MarimoErrorOutput.tsx +7 -7
  77. package/src/components/editor/output/__tests__/traceback.test.tsx +4 -4
  78. package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +4 -4
  79. package/src/components/editor/renderers/vertical-layout/useFocusFirstEditor.ts +8 -1
  80. package/src/components/storage/storage-inspector.tsx +1 -2
  81. package/src/components/tracing/tracing.tsx +3 -1
  82. package/src/core/ai/__tests__/staged-cells.test.ts +9 -8
  83. package/src/core/ai/context/providers/__tests__/cell-output.test.ts +31 -31
  84. package/src/core/ai/context/providers/__tests__/datasource.test.ts +3 -3
  85. package/src/core/ai/context/providers/__tests__/tables.test.ts +3 -2
  86. package/src/core/ai/context/providers/__tests__/variable.test.ts +84 -63
  87. package/src/core/ai/tools/__tests__/edit-notebook-tool.test.ts +10 -9
  88. package/src/core/ai/tools/__tests__/run-cells-tool.test.ts +6 -6
  89. package/src/core/ai/tools/edit-notebook-tool.ts +3 -3
  90. package/src/core/cells/__tests__/add-missing-import.test.ts +3 -3
  91. package/src/core/cells/__tests__/cells.test.ts +192 -135
  92. package/src/core/cells/__tests__/focus.test.ts +5 -4
  93. package/src/core/cells/__tests__/logs.test.ts +13 -12
  94. package/src/core/cells/__tests__/pending-delete-service.test.tsx +3 -3
  95. package/src/core/cells/__tests__/runs.test.ts +22 -21
  96. package/src/core/cells/__tests__/scrollCellIntoView.test.ts +8 -7
  97. package/src/core/cells/__tests__/session.test.ts +23 -22
  98. package/src/core/cells/cells.ts +1 -1
  99. package/src/core/cells/ids.ts +5 -5
  100. package/src/core/cells/logs.ts +2 -2
  101. package/src/core/cells/runs.ts +6 -8
  102. package/src/core/codemirror/__tests__/format.test.ts +34 -36
  103. package/src/core/codemirror/__tests__/setup.test.ts +2 -2
  104. package/src/core/codemirror/cells/__tests__/extensions.test.ts +114 -0
  105. package/src/core/codemirror/cells/__tests__/traceback-decorations.test.ts +33 -32
  106. package/src/core/codemirror/cells/extensions.ts +66 -23
  107. package/src/core/codemirror/copilot/__tests__/getCodes.test.ts +12 -13
  108. package/src/core/codemirror/language/__tests__/utils.test.ts +3 -3
  109. package/src/core/codemirror/language/embedded/__tests__/embedded-python.test.ts +7 -8
  110. package/src/core/codemirror/lsp/__tests__/notebook-lsp.test.ts +4 -3
  111. package/src/core/codemirror/reactive-references/__tests__/analyzer.test.ts +7 -6
  112. package/src/core/codemirror/reactive-references/analyzer.ts +2 -2
  113. package/src/core/codemirror/rtc/loro/__tests__/sync.test.ts +52 -0
  114. package/src/core/codemirror/rtc/loro/sync.ts +1 -0
  115. package/src/core/datasets/__tests__/data-source.test.ts +5 -6
  116. package/src/core/datasets/state.ts +1 -1
  117. package/src/core/errors/__tests__/errors.test.ts +2 -1
  118. package/src/core/export/__tests__/hooks.test.ts +37 -36
  119. package/src/core/islands/main.ts +2 -7
  120. package/src/core/kernel/__tests__/handlers.test.ts +5 -4
  121. package/src/core/kernel/handlers.ts +7 -4
  122. package/src/core/network/DeferredRequestRegistry.ts +2 -2
  123. package/src/core/network/__tests__/CachingRequestRegistry.test.ts +9 -10
  124. package/src/core/network/__tests__/DeferredRequestRegistry.test.ts +4 -6
  125. package/src/core/static/__tests__/virtual-file-tracker.test.ts +8 -8
  126. package/src/core/static/virtual-file-tracker.ts +1 -1
  127. package/src/core/storage/__tests__/state.test.ts +31 -21
  128. package/src/core/storage/state.ts +1 -1
  129. package/src/core/variables/__tests__/state.test.ts +6 -6
  130. package/src/core/variables/types.ts +2 -2
  131. package/src/core/wasm/__tests__/state.test.ts +8 -8
  132. package/src/core/websocket/useMarimoKernelConnection.tsx +12 -15
  133. package/src/plugins/impl/anywidget/model.ts +1 -2
  134. package/src/stories/cell.stories.tsx +8 -8
  135. package/src/stories/layout/vertical/one-column.stories.tsx +9 -8
  136. package/src/stories/log-viewer.stories.tsx +8 -8
  137. package/src/stories/variables.stories.tsx +2 -2
  138. package/src/utils/__tests__/download.test.tsx +19 -18
  139. package/src/utils/json/base64.ts +3 -3
  140. package/src/utils/traceback.ts +5 -3
  141. package/dist/assets/tracing-DFGiZoMP.js +0 -1
@@ -1,5 +1,6 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  import { beforeEach, describe, expect, it } from "vitest";
3
+ import { variableName } from "@/__tests__/branded";
3
4
  import type { VariableName } from "../../variables/types";
4
5
  import { exportedForTesting } from "../state";
5
6
  import type { StorageEntry, StorageNamespace, StorageState } from "../types";
@@ -7,7 +8,7 @@ import type { StorageEntry, StorageNamespace, StorageState } from "../types";
7
8
  const { initialState, reducer, createActions } = exportedForTesting;
8
9
 
9
10
  function makeNamespace(
10
- overrides: Partial<StorageNamespace> & { name: string },
11
+ overrides: Partial<StorageNamespace> & { name: VariableName },
11
12
  ): StorageNamespace {
12
13
  return {
13
14
  backendType: overrides.backendType ?? "obstore",
@@ -53,8 +54,14 @@ describe("storage state", () => {
53
54
 
54
55
  describe("setNamespaces", () => {
55
56
  it("should add namespaces from an empty state", () => {
56
- const ns1 = makeNamespace({ name: "my_s3", protocol: "s3" });
57
- const ns2 = makeNamespace({ name: "my_gcs", protocol: "gcs" });
57
+ const ns1 = makeNamespace({
58
+ name: variableName("my_s3"),
59
+ protocol: "s3",
60
+ });
61
+ const ns2 = makeNamespace({
62
+ name: variableName("my_gcs"),
63
+ protocol: "gcs",
64
+ });
58
65
 
59
66
  actions.setNamespaces({ namespaces: [ns1, ns2] });
60
67
 
@@ -63,15 +70,18 @@ describe("storage state", () => {
63
70
 
64
71
  it("should merge namespaces by name, replacing existing ones", () => {
65
72
  const nsOld = makeNamespace({
66
- name: "my_s3",
73
+ name: variableName("my_s3"),
67
74
  protocol: "s3",
68
75
  rootPath: "/old",
69
76
  });
70
- const nsOther = makeNamespace({ name: "my_gcs", protocol: "gcs" });
77
+ const nsOther = makeNamespace({
78
+ name: variableName("my_gcs"),
79
+ protocol: "gcs",
80
+ });
71
81
  actions.setNamespaces({ namespaces: [nsOld, nsOther] });
72
82
 
73
83
  const nsUpdated = makeNamespace({
74
- name: "my_s3",
84
+ name: variableName("my_s3"),
75
85
  protocol: "s3",
76
86
  rootPath: "/new",
77
87
  });
@@ -82,10 +92,10 @@ describe("storage state", () => {
82
92
  });
83
93
 
84
94
  it("should add new namespaces alongside existing ones", () => {
85
- const ns1 = makeNamespace({ name: "ns1" });
95
+ const ns1 = makeNamespace({ name: variableName("ns1") });
86
96
  actions.setNamespaces({ namespaces: [ns1] });
87
97
 
88
- const ns2 = makeNamespace({ name: "ns2" });
98
+ const ns2 = makeNamespace({ name: variableName("ns2") });
89
99
  actions.setNamespaces({ namespaces: [ns2] });
90
100
 
91
101
  expect(state.namespaces).toHaveLength(2);
@@ -101,7 +111,7 @@ describe("storage state", () => {
101
111
  });
102
112
 
103
113
  actions.setNamespaces({
104
- namespaces: [makeNamespace({ name: "ns" })],
114
+ namespaces: [makeNamespace({ name: variableName("ns") })],
105
115
  });
106
116
 
107
117
  expect(state.entriesByPath.get("ns::")).toEqual([entry]);
@@ -205,7 +215,7 @@ describe("storage state", () => {
205
215
  });
206
216
 
207
217
  it("should not affect namespaces", () => {
208
- const ns = makeNamespace({ name: "ns" });
218
+ const ns = makeNamespace({ name: variableName("ns") });
209
219
  actions.setNamespaces({ namespaces: [ns] });
210
220
 
211
221
  actions.setEntries({
@@ -263,7 +273,7 @@ describe("storage state", () => {
263
273
  });
264
274
 
265
275
  it("should not affect namespaces", () => {
266
- const ns = makeNamespace({ name: "my_s3" });
276
+ const ns = makeNamespace({ name: variableName("my_s3") });
267
277
  actions.setNamespaces({ namespaces: [ns] });
268
278
  actions.setEntries({
269
279
  namespace: "my_s3",
@@ -293,31 +303,31 @@ describe("storage state", () => {
293
303
 
294
304
  describe("filterFromVariables", () => {
295
305
  it("should keep namespaces whose variable is still in scope", () => {
296
- const ns1 = makeNamespace({ name: "var_a" });
297
- const ns2 = makeNamespace({ name: "var_b" });
306
+ const ns1 = makeNamespace({ name: variableName("var_a") });
307
+ const ns2 = makeNamespace({ name: variableName("var_b") });
298
308
  actions.setNamespaces({ namespaces: [ns1, ns2] });
299
309
 
300
310
  actions.filterFromVariables([
301
- "var_a" as VariableName,
302
- "var_b" as VariableName,
311
+ variableName("var_a"),
312
+ variableName("var_b"),
303
313
  ]);
304
314
 
305
315
  expect(state.namespaces).toEqual([ns1, ns2]);
306
316
  });
307
317
 
308
318
  it("should remove namespaces whose variable is no longer in scope", () => {
309
- const ns1 = makeNamespace({ name: "var_a" });
310
- const ns2 = makeNamespace({ name: "var_b" });
319
+ const ns1 = makeNamespace({ name: variableName("var_a") });
320
+ const ns2 = makeNamespace({ name: variableName("var_b") });
311
321
  actions.setNamespaces({ namespaces: [ns1, ns2] });
312
322
 
313
- actions.filterFromVariables(["var_a" as VariableName]);
323
+ actions.filterFromVariables([variableName("var_a")]);
314
324
 
315
325
  expect(state.namespaces).toEqual([ns1]);
316
326
  });
317
327
 
318
328
  it("should remove all named namespaces when given an empty variable list", () => {
319
- const ns1 = makeNamespace({ name: "var_a" });
320
- const ns2 = makeNamespace({ name: "var_b" });
329
+ const ns1 = makeNamespace({ name: variableName("var_a") });
330
+ const ns2 = makeNamespace({ name: variableName("var_b") });
321
331
  actions.setNamespaces({ namespaces: [ns1, ns2] });
322
332
 
323
333
  actions.filterFromVariables([]);
@@ -326,7 +336,7 @@ describe("storage state", () => {
326
336
  });
327
337
 
328
338
  it("should not affect entriesByPath", () => {
329
- const ns = makeNamespace({ name: "ns" });
339
+ const ns = makeNamespace({ name: variableName("ns") });
330
340
  actions.setNamespaces({ namespaces: [ns] });
331
341
 
332
342
  const entry = makeEntry({ path: "file.txt" });
@@ -71,7 +71,7 @@ const {
71
71
  const names = new Set(variableNames);
72
72
  // Filter out namespaces whose backing variable is no longer in scope
73
73
  const namespaces = state.namespaces.filter((ns) => {
74
- return names.has(ns.name as VariableName);
74
+ return names.has(ns.name);
75
75
  });
76
76
  return { ...state, namespaces };
77
77
  },
@@ -1,19 +1,19 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  import { beforeEach, describe, expect, it } from "vitest";
3
- import type { CellId } from "@/core/cells/ids";
3
+ import { cellId, variableName } from "@/__tests__/branded";
4
4
  import { exportedForTesting } from "../state";
5
- import type { VariableName, Variables } from "../types";
5
+ import type { Variables } from "../types";
6
6
 
7
7
  const { initialState, reducer, createActions } = exportedForTesting;
8
8
 
9
9
  const CellIds = {
10
- a: "a" as CellId,
11
- b: "b" as CellId,
10
+ a: cellId("a"),
11
+ b: cellId("b"),
12
12
  };
13
13
 
14
14
  const Names = {
15
- x: "x" as VariableName,
16
- y: "y" as VariableName,
15
+ x: variableName("x"),
16
+ y: variableName("y"),
17
17
  };
18
18
 
19
19
  describe("cell reducer", () => {
@@ -1,9 +1,9 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
- import type { TypedString } from "../../utils/typed";
3
+ import type { components } from "@marimo-team/marimo-api";
4
4
  import type { CellId } from "../cells/ids";
5
5
 
6
- export type VariableName = TypedString<"VariableName">;
6
+ export type VariableName = components["schemas"]["VariableName"];
7
7
 
8
8
  export interface Variable {
9
9
  name: VariableName;
@@ -2,9 +2,9 @@
2
2
 
3
3
  import { createRef } from "react";
4
4
  import { describe, expect, it } from "vitest";
5
+ import { cellId } from "@/__tests__/branded";
5
6
  import type { NotebookState } from "@/core/cells/cells";
6
7
  import { initialNotebookState, notebookAtom } from "@/core/cells/cells";
7
- import type { CellId } from "@/core/cells/ids";
8
8
  import { createCell, createCellRuntimeState } from "@/core/cells/types";
9
9
  import type { OutputMessage } from "@/core/kernel/messages";
10
10
  import { store } from "@/core/state/jotai";
@@ -17,17 +17,17 @@ describe("hasAnyOutputAtom", () => {
17
17
  ): NotebookState => ({
18
18
  ...initialNotebookState(),
19
19
  cellIds: new MultiColumn([
20
- CollapsibleTree.from(outputs.map((_, i) => `${i}` as CellId)),
20
+ CollapsibleTree.from(outputs.map((_, i) => cellId(`${i}`))),
21
21
  ]),
22
22
  cellData: Object.fromEntries(
23
23
  outputs.map((_, i) => [
24
- `${i}` as CellId,
25
- createCell({ id: `${i}` as CellId }),
24
+ cellId(`${i}`),
25
+ createCell({ id: cellId(`${i}`) }),
26
26
  ]),
27
27
  ),
28
28
  cellRuntime: Object.fromEntries(
29
29
  outputs.map((output, i) => [
30
- `${i}` as CellId,
30
+ `${i}`,
31
31
  createCellRuntimeState({
32
32
  output,
33
33
  status: "queued",
@@ -36,7 +36,7 @@ describe("hasAnyOutputAtom", () => {
36
36
  ]),
37
37
  ),
38
38
  cellHandles: Object.fromEntries(
39
- outputs.map((_, i) => [`${i}` as CellId, createRef()]),
39
+ outputs.map((_, i) => [cellId(`${i}`), createRef()]),
40
40
  ),
41
41
  });
42
42
 
@@ -90,8 +90,8 @@ describe("hasAnyOutputAtom", () => {
90
90
 
91
91
  it("should return true when all outputs are idle", () => {
92
92
  const notebookState = createNotebookState([null, null]);
93
- const cellId0 = "0" as CellId;
94
- const cellId1 = "1" as CellId;
93
+ const cellId0 = cellId("0");
94
+ const cellId1 = cellId("1");
95
95
  // Some idle cell, so returns false
96
96
  store.set(notebookAtom, {
97
97
  ...notebookState,
@@ -24,7 +24,7 @@ import { Logger } from "@/utils/Logger";
24
24
  import { reloadSafe } from "@/utils/reload-safe";
25
25
  import { useAlertActions } from "../alerts/state";
26
26
  import { cacheInfoAtom } from "../cache/requests";
27
- import { type CellId, SCRATCH_CELL_ID, type UIElementId } from "../cells/ids";
27
+ import { SCRATCH_CELL_ID } from "../cells/ids";
28
28
  import { useRunsActions } from "../cells/runs";
29
29
  import { focusAndScrollCellOutputIntoView } from "../cells/scrollCellIntoView";
30
30
  import type { CellData } from "../cells/types";
@@ -153,7 +153,7 @@ export function useMarimoKernelConnection(opts: {
153
153
  if (uiElement) {
154
154
  const buffers = safeExtractSetUIElementMessageBuffers(msg.data);
155
155
  UI_ELEMENT_REGISTRY.broadcastMessage(
156
- uiElement as UIElementId,
156
+ uiElement,
157
157
  msg.data.message,
158
158
  buffers,
159
159
  );
@@ -173,14 +173,11 @@ export function useMarimoKernelConnection(opts: {
173
173
  AUTOCOMPLETER.resolve(msg.data.completion_id as RequestId, msg.data);
174
174
  return;
175
175
  case "function-call-result":
176
- FUNCTIONS_REGISTRY.resolve(
177
- msg.data.function_call_id as RequestId,
178
- msg.data,
179
- );
176
+ FUNCTIONS_REGISTRY.resolve(msg.data.function_call_id, msg.data);
180
177
  return;
181
178
  case "cell-op": {
182
179
  handleCellNotificationeration(msg.data, handleCellMessage);
183
- const cellData = getNotebook().cellData[msg.data.cell_id as CellId];
180
+ const cellData = getNotebook().cellData[msg.data.cell_id];
184
181
  if (!cellData) {
185
182
  return;
186
183
  }
@@ -195,8 +192,8 @@ export function useMarimoKernelConnection(opts: {
195
192
  setVariables(
196
193
  msg.data.variables.map((v) => ({
197
194
  name: v.name as VariableName,
198
- declaredBy: v.declared_by as CellId[],
199
- usedBy: v.used_by as CellId[],
195
+ declaredBy: v.declared_by,
196
+ usedBy: v.used_by,
200
197
  })),
201
198
  );
202
199
  filterDatasetsFromVariables(
@@ -271,16 +268,16 @@ export function useMarimoKernelConnection(opts: {
271
268
  addColumnPreview(msg.data);
272
269
  return;
273
270
  case "sql-table-preview":
274
- PreviewSQLTable.resolve(msg.data.request_id as RequestId, msg.data);
271
+ PreviewSQLTable.resolve(msg.data.request_id, msg.data);
275
272
  return;
276
273
  case "sql-table-list-preview":
277
- PreviewSQLTableList.resolve(msg.data.request_id as RequestId, msg.data);
274
+ PreviewSQLTableList.resolve(msg.data.request_id, msg.data);
278
275
  return;
279
276
  case "validate-sql-result":
280
277
  ValidateSQL.resolve(msg.data.request_id as RequestId, msg.data);
281
278
  return;
282
279
  case "secret-keys-result":
283
- SECRETS_REGISTRY.resolve(msg.data.request_id as RequestId, msg.data);
280
+ SECRETS_REGISTRY.resolve(msg.data.request_id, msg.data);
284
281
  return;
285
282
  case "cache-info":
286
283
  setCacheInfo(msg.data);
@@ -310,19 +307,19 @@ export function useMarimoKernelConnection(opts: {
310
307
  return;
311
308
 
312
309
  case "focus-cell":
313
- focusAndScrollCellOutputIntoView(msg.data.cell_id as CellId);
310
+ focusAndScrollCellOutputIntoView(msg.data.cell_id);
314
311
  return;
315
312
  case "update-cell-codes":
316
313
  setCellCodes({
317
314
  codes: msg.data.codes,
318
- ids: msg.data.cell_ids as CellId[],
315
+ ids: msg.data.cell_ids,
319
316
  codeIsStale: msg.data.code_is_stale,
320
317
  names: msg.data.names,
321
318
  configs: msg.data.configs,
322
319
  });
323
320
  return;
324
321
  case "update-cell-ids":
325
- setCellIds({ cellIds: msg.data.cell_ids as CellId[] });
322
+ setCellIds({ cellIds: msg.data.cell_ids });
326
323
  return;
327
324
  default:
328
325
  logNever(msg.data);
@@ -323,8 +323,7 @@ export async function handleWidgetMessage(
323
323
  const msg = notification.message;
324
324
 
325
325
  // Decode base64 buffers to DataViews (present in open/update/custom messages)
326
- const base64Buffers: Base64String[] =
327
- "buffers" in msg ? (msg.buffers as Base64String[]) : [];
326
+ const base64Buffers: Base64String[] = "buffers" in msg ? msg.buffers : [];
328
327
  const buffers = base64Buffers.map(base64ToDataView);
329
328
 
330
329
  switch (msg.method) {
@@ -3,6 +3,7 @@
3
3
  import type { Meta, StoryObj } from "@storybook/react-vite";
4
4
  import { createStore, Provider } from "jotai";
5
5
  import { createRef } from "react";
6
+ import { cellId } from "@/__tests__/branded";
6
7
  import { type NotebookState, notebookAtom } from "@/core/cells/cells";
7
8
  import {
8
9
  type CellRuntimeState,
@@ -18,7 +19,6 @@ import { MultiColumn } from "@/utils/id-tree";
18
19
  import type { Milliseconds, Seconds } from "@/utils/time";
19
20
  import { Cell as EditorCell } from "../components/editor/notebook-cell";
20
21
  import { TooltipProvider } from "../components/ui/tooltip";
21
- import type { CellId } from "../core/cells/ids";
22
22
 
23
23
  type Story = StoryObj<typeof Cell>;
24
24
 
@@ -34,11 +34,11 @@ const Cell: React.FC<{
34
34
  config?: CellConfig;
35
35
  };
36
36
  }> = ({ overrides = {} }) => {
37
- const cellId = "1" as CellId;
37
+ const cid = cellId("1");
38
38
  const notebook: NotebookState = {
39
39
  cellData: {
40
- [cellId]: {
41
- id: cellId,
40
+ [cid]: {
41
+ id: cid,
42
42
  name: "cell_1",
43
43
  code: "import marimo as mo",
44
44
  edited: overrides.edited ?? false,
@@ -52,9 +52,9 @@ const Cell: React.FC<{
52
52
  lastExecutionTime: null,
53
53
  },
54
54
  },
55
- cellIds: MultiColumn.from([[cellId]]),
55
+ cellIds: MultiColumn.from([[cid]]),
56
56
  cellRuntime: {
57
- [cellId]: createCellRuntimeState({
57
+ [cid]: createCellRuntimeState({
58
58
  output: overrides.output ?? null,
59
59
  runElapsedTimeMs: overrides.runElapsedTimeMs ?? (10 as Milliseconds),
60
60
  status: overrides.status ?? "idle",
@@ -70,7 +70,7 @@ const Cell: React.FC<{
70
70
  }),
71
71
  },
72
72
  cellHandles: {
73
- [cellId]: createRef(),
73
+ [cid]: createRef(),
74
74
  },
75
75
  cellLogs: [],
76
76
  history: [],
@@ -86,7 +86,7 @@ const Cell: React.FC<{
86
86
  <Provider store={store}>
87
87
  <TooltipProvider>
88
88
  <EditorCell
89
- cellId={cellId}
89
+ cellId={cid}
90
90
  theme={"light"}
91
91
  showPlaceholder={false}
92
92
  mode={"edit"}
@@ -3,6 +3,7 @@
3
3
  import type { Meta } from "@storybook/react-vite";
4
4
  import { createStore, Provider } from "jotai";
5
5
  import { createRef } from "react";
6
+ import { cellId } from "@/__tests__/branded";
6
7
  import { type NotebookState, notebookAtom } from "@/core/cells/cells";
7
8
  import { createCellRuntimeState } from "@/core/cells/types";
8
9
  import { defaultUserConfig, parseAppConfig } from "@/core/config/config-schema";
@@ -99,8 +100,8 @@ export default {
99
100
  type W = Window & { __MARIMO_STATIC__?: { files: Record<string, unknown> } };
100
101
 
101
102
  const EditModeCodeShown = () => {
102
- const cellId = "Hbol" as CellId;
103
- const notebook = createLongReprNotebook(cellId);
103
+ const cid = cellId("Hbol");
104
+ const notebook = createLongReprNotebook(cid);
104
105
 
105
106
  const store = createStore();
106
107
  store.set(notebookAtom, notebook);
@@ -124,8 +125,8 @@ const EditModeCodeShown = () => {
124
125
  };
125
126
 
126
127
  const EditModeCodeHidden = () => {
127
- const cellId = "Hbol" as CellId;
128
- const notebook = createLongReprNotebook(cellId, true);
128
+ const cid = cellId("Hbol");
129
+ const notebook = createLongReprNotebook(cid, true);
129
130
 
130
131
  const store = createStore();
131
132
  store.set(notebookAtom, notebook);
@@ -149,8 +150,8 @@ const EditModeCodeHidden = () => {
149
150
  };
150
151
 
151
152
  const ReadModeCodeShown = () => {
152
- const cellId = "Hbol" as CellId;
153
- const notebook = createLongReprNotebook(cellId);
153
+ const cid = cellId("Hbol");
154
+ const notebook = createLongReprNotebook(cid);
154
155
 
155
156
  const store = createStore();
156
157
  store.set(notebookAtom, notebook);
@@ -168,8 +169,8 @@ const ReadModeCodeShown = () => {
168
169
  };
169
170
 
170
171
  const ReadModeCodeHidden = () => {
171
- const cellId = "Hbol" as CellId;
172
- const notebook = createLongReprNotebook(cellId);
172
+ const cid = cellId("Hbol");
173
+ const notebook = createLongReprNotebook(cid);
173
174
 
174
175
  const store = createStore();
175
176
  store.set(notebookAtom, notebook);
@@ -1,7 +1,7 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  import type { Meta, StoryObj } from "@storybook/react-vite";
3
+ import { cellId } from "@/__tests__/branded";
3
4
  import { LogViewer } from "@/components/editor/chrome/panels/logs-panel";
4
- import type { CellId } from "@/core/cells/ids";
5
5
  import { Dialog } from "../components/ui/dialog";
6
6
  import { TooltipProvider } from "../components/ui/tooltip";
7
7
 
@@ -23,37 +23,37 @@ export const Primary: Story = {
23
23
  {
24
24
  timestamp: Date.now(),
25
25
  level: "stdout",
26
- cellId: "cell1" as CellId,
26
+ cellId: cellId("cell1"),
27
27
  message: "Hello world!",
28
28
  },
29
29
  {
30
30
  timestamp: Date.now(),
31
31
  level: "stdout",
32
- cellId: "cell1" as CellId,
32
+ cellId: cellId("cell1"),
33
33
  message: "Running cell...",
34
34
  },
35
35
  {
36
36
  timestamp: Date.now(),
37
37
  level: "stdout",
38
- cellId: "cell1" as CellId,
38
+ cellId: cellId("cell1"),
39
39
  message: "Done!",
40
40
  },
41
41
  {
42
42
  timestamp: Date.now(),
43
43
  level: "stderr",
44
- cellId: "cell2" as CellId,
44
+ cellId: cellId("cell2"),
45
45
  message: "Output is too large!",
46
46
  },
47
47
  {
48
48
  timestamp: Date.now(),
49
49
  level: "stderr",
50
- cellId: "cell2" as CellId,
50
+ cellId: cellId("cell2"),
51
51
  message: "String length is too short.".repeat(100),
52
52
  },
53
- ...Array.from({ length: 100 }).map((_, index) => ({
53
+ ...Array.from({ length: 100 }).map(() => ({
54
54
  timestamp: Date.now(),
55
55
  level: "stdout" as const,
56
- cellId: "cell1" as CellId,
56
+ cellId: cellId("cell1"),
57
57
  message: "Running cell...",
58
58
  })),
59
59
  ]}
@@ -1,7 +1,7 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  import type { Meta, StoryObj } from "@storybook/react-vite";
3
+ import { cellId } from "@/__tests__/branded";
3
4
  import { VariableTable } from "@/components/variables/variables-table";
4
- import type { CellId } from "@/core/cells/ids";
5
5
 
6
6
  const meta: Meta<typeof VariableTable> = {
7
7
  title: "VariableTable",
@@ -51,7 +51,7 @@ export const Primary: Story = {
51
51
  <div className="max-w-4xl">
52
52
  <VariableTable
53
53
  variables={variables}
54
- cellIds={["2", "1", "3"] as CellId[]}
54
+ cellIds={[cellId("2"), cellId("1"), cellId("3")]}
55
55
  />
56
56
  </div>
57
57
  ),