@marimo-team/islands 0.21.1-dev18 → 0.21.1-dev21

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.
@@ -5,7 +5,7 @@ import { g as Logger } from "./button-BKkuUpZh.js";
5
5
  import "./Combination-BBPQRrDo.js";
6
6
  import { t as require_jsx_runtime } from "./jsx-runtime-CTBg5pdT.js";
7
7
  import "./react-dom-CqtLRVZP.js";
8
- import { d as CopyClipboardIcon, n as loadLanguage, r as esm_default, t as langs } from "./esm-BxfaUFPY.js";
8
+ import { f as CopyClipboardIcon, n as loadLanguage, r as esm_default, t as langs } from "./esm-BLobyqMs.js";
9
9
  import "./dist-DOoqn-VL.js";
10
10
  import "./dist-BGZ7TWS9.js";
11
11
  import "./dist-BpMlUdNO.js";
@@ -4374,13 +4374,14 @@ function loadLanguage(e6) {
4374
4374
  export {
4375
4375
  _extends as a,
4376
4376
  setDiagnostics as c,
4377
- CopyClipboardIcon as d,
4377
+ insertTab as d,
4378
+ CopyClipboardIcon as f,
4378
4379
  minimalSetup as i,
4379
- historyField as l,
4380
+ history as l,
4380
4381
  loadLanguage as n,
4381
4382
  forEachDiagnostic as o,
4382
4383
  esm_default as r,
4383
4384
  linter as s,
4384
4385
  langs as t,
4385
- insertTab as u
4386
+ historyField as u
4386
4387
  };
package/dist/main.js CHANGED
@@ -34,7 +34,7 @@ import { $ as __awaiter, A as custom, B as record, C as ZodUnion$1, D as any, E
34
34
  import { t as require_jsx_runtime } from "./jsx-runtime-CTBg5pdT.js";
35
35
  import { t as require_react_dom } from "./react-dom-CqtLRVZP.js";
36
36
  import { a as TooltipRoot, i as TooltipProvider, n as TooltipContent, o as TooltipTrigger, r as TooltipPortal, s as TooltipProvider$1, t as Tooltip } from "./tooltip-CKG75XQa.js";
37
- import { a as _extends$5, c as setDiagnostics, d as CopyClipboardIcon, i as minimalSetup, l as historyField, o as forEachDiagnostic, r as esm_default, s as linter, t as langs, u as insertTab } from "./esm-BxfaUFPY.js";
37
+ import { a as _extends$5, c as setDiagnostics, d as insertTab, f as CopyClipboardIcon, i as minimalSetup, l as history, o as forEachDiagnostic, r as esm_default, s as linter, t as langs, u as historyField } from "./esm-BLobyqMs.js";
38
38
  import { i as toInteger_default, n as _baseSet_default } from "./_basePickBy-pTDW2_2A.js";
39
39
  import { i as get_default } from "./hasIn-B9AbGLj3.js";
40
40
  import { n as pick_default, t as range_default } from "./range-BKaWvVUE.js";
@@ -15378,9 +15378,7 @@ ${d.join("\n")}`;
15378
15378
  combine: (e) => e.find((e2) => e2 !== void 0)
15379
15379
  });
15380
15380
  }
15381
- singleFacet(), singleFacet(), singleFacet();
15382
- const cellIdState$1 = singleFacet();
15383
- singleFacet();
15381
+ const completionConfigState = singleFacet(), hotkeysProviderState = singleFacet(), placeholderState = singleFacet(), cellIdState = singleFacet(), lspConfigState = singleFacet(), historyCompartment = new Compartment();
15384
15382
  function notebookIsRunning(e) {
15385
15383
  return Object.values(e.cellRuntime).some((e2) => e2.status === "running");
15386
15384
  }
@@ -15427,7 +15425,7 @@ ${d.join("\n")}`;
15427
15425
  }
15428
15426
  const cellActionsState = Facet$1.define({
15429
15427
  combine: (e) => e[0]
15430
- }), cellIdState = Facet$1.define({
15428
+ }), cellIdState$1 = Facet$1.define({
15431
15429
  combine: (e) => e[0]
15432
15430
  });
15433
15431
  var BigQuery = {
@@ -24938,7 +24936,7 @@ ${d.join("\n")}`;
24938
24936
  });
24939
24937
  return;
24940
24938
  }
24941
- let S = f.transformIn(y)[0], w = e.state.facet(cellActionsState), E = e.state.facet(cellIdState$1);
24939
+ let S = f.transformIn(y)[0], w = e.state.facet(cellActionsState), E = e.state.facet(cellIdState);
24942
24940
  w.updateCellCode({
24943
24941
  cellId: E,
24944
24942
  code: S,
@@ -31242,6 +31240,10 @@ ${c.sqlString}
31242
31240
  function updateSQLDialectFromConnection(e, r) {
31243
31241
  updateSQLDialect(e, SCHEMA_CACHE.getDialect(r));
31244
31242
  }
31243
+ function initializeSQLDialect(e) {
31244
+ let r = getSQLMetadata(e.state).engine;
31245
+ updateSQLDialect(e, SCHEMA_CACHE.getDialect(r));
31246
+ }
31245
31247
  function getSQLMetadata(e) {
31246
31248
  return e.field(languageMetadataField);
31247
31249
  }
@@ -31314,7 +31316,7 @@ ${c.sqlString}
31314
31316
  var SQL_VALIDATION_DEBOUNCE_MS = 300;
31315
31317
  function sqlValidationExtension() {
31316
31318
  return ViewPlugin.define((e) => {
31317
- let r, c = null, d = e.state.facet(cellIdState);
31319
+ let r, c = null, d = e.state.facet(cellIdState$1);
31318
31320
  return {
31319
31321
  update(e2) {
31320
31322
  if (!e2.docChanged) return;
@@ -31956,7 +31958,7 @@ ${c.sqlString}
31956
31958
  let { spanProps: f, inputProps: _ } = useAutoGrowInputProps(d), v;
31957
31959
  r[1] === c.state ? v = r[2] : (v = c.state.field(languageAdapterState), r[1] = c.state, r[2] = v);
31958
31960
  let y = v, S;
31959
- r[3] === c.state ? S = r[4] : (S = c.state.facet(cellIdState), r[3] = c.state, r[4] = S);
31961
+ r[3] === c.state ? S = r[4] : (S = c.state.facet(cellIdState$1), r[3] = c.state, r[4] = S);
31960
31962
  let w = S, E;
31961
31963
  r[5] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (E = (0, import_jsx_runtime.jsx)("div", {}), r[5] = E) : E = r[5];
31962
31964
  let O = E, M = false, I;
@@ -32188,7 +32190,7 @@ ${c.sqlString}
32188
32190
  })
32189
32191
  }), r[98] = O, r[99] = y.type, r[100] = G, r[101] = q) : q = r[101], q;
32190
32192
  };
32191
- new Compartment();
32193
+ var languageCompartment = new Compartment();
32192
32194
  const setLanguageAdapter = StateEffect.define(), languageAdapterState = StateField.define({
32193
32195
  create() {
32194
32196
  return LanguageAdapters.python;
@@ -32199,13 +32201,61 @@ ${c.sqlString}
32199
32201
  },
32200
32202
  provide: (e) => showPanel.from(e, (e2) => e2.type === "python" ? null : (e3) => createPanel(e3, LanguagePanelComponent))
32201
32203
  });
32204
+ function updateLanguageAdapterAndCode({ view: e, nextLanguage: r, opts: c }) {
32205
+ let d = e.state.field(languageAdapterState), f = e.state.doc.toString(), _ = e.state.facet(completionConfigState), v = e.state.facet(hotkeysProviderState), y = e.state.facet(placeholderState), S = e.state.facet(cellIdState), w = e.state.facet(lspConfigState), E = e.state.field(languageMetadataField), O = e.state.selection.main.head, M;
32206
+ if (c.keepCodeAsIs) M = f, d.type !== r.type && (E = {
32207
+ ...r.defaultMetadata
32208
+ });
32209
+ else {
32210
+ let [e2, c2] = d.transformOut(f, E), [_2, v2, y2] = r.transformIn(e2);
32211
+ O += c2, O -= v2, O = clamp(O, 0, _2.length), M = _2, E = y2;
32212
+ }
32213
+ e.dispatch({
32214
+ effects: [
32215
+ setLanguageAdapter.of(r),
32216
+ setLanguageMetadata.of(E),
32217
+ languageCompartment.reconfigure(r.getExtension(S, _, v, y, w)),
32218
+ historyCompartment.reconfigure([]),
32219
+ formattingChangeEffect.of(true)
32220
+ ],
32221
+ changes: c.keepCodeAsIs ? void 0 : {
32222
+ from: 0,
32223
+ to: e.state.doc.length,
32224
+ insert: M
32225
+ },
32226
+ selection: c.keepCodeAsIs ? void 0 : EditorSelection.cursor(O)
32227
+ }), e.dispatch({
32228
+ effects: [
32229
+ historyCompartment.reconfigure([
32230
+ history()
32231
+ ])
32232
+ ]
32233
+ }), r.type === "sql" && initializeSQLDialect(e);
32234
+ }
32235
+ function languageAdapterFromCode(e) {
32236
+ return e ? LanguageAdapters.markdown.isSupported(e) ? LanguageAdapters.markdown : LanguageAdapters.sql.isSupported(e) ? LanguageAdapters.sql : LanguageAdapters.python : LanguageAdapters.python;
32237
+ }
32238
+ function switchLanguage(e, r) {
32239
+ e.state.field(languageAdapterState).type !== r.language && updateLanguageAdapterAndCode({
32240
+ view: e,
32241
+ nextLanguage: LanguageAdapters[r.language],
32242
+ opts: {
32243
+ keepCodeAsIs: r.keepCodeAsIs ?? false
32244
+ }
32245
+ });
32246
+ }
32202
32247
  function getEditorCodeAsPython(e, r, c) {
32203
32248
  let d = e.state.field(languageAdapterState), f = e.state.field(languageMetadataField), _ = e.state.doc.toString();
32204
32249
  return r === void 0 ? d.transformOut(_, f)[0] : d.transformOut(_.slice(r, c), f)[0];
32205
32250
  }
32206
32251
  function updateEditorCodeFromPython(e, r) {
32207
- let [c] = e.state.field(languageAdapterState).transformIn(r);
32208
- return replaceEditorContent(e, c), c;
32252
+ let c = e.state.field(languageAdapterState), d = languageAdapterFromCode(r);
32253
+ d.type !== c.type && switchLanguage(e, {
32254
+ language: d.type,
32255
+ keepCodeAsIs: true
32256
+ });
32257
+ let [f] = e.state.field(languageAdapterState).transformIn(r);
32258
+ return replaceEditorContent(e, f), f;
32209
32259
  }
32210
32260
  function splitEditor(e) {
32211
32261
  let r = e.state.selection.main.head, c = e.state.doc.toString(), d = c.length > 0 && c[r - 1] === "\n", f = c.length > 0 && c[r] === "\n", _ = d ? r - 1 : r, v = f ? r + 1 : r;
@@ -37063,7 +37113,10 @@ ${c.sqlString}
37063
37113
  return (_a3 = r[e2]) == null ? void 0 : _a3.name;
37064
37114
  }).filter(Boolean);
37065
37115
  };
37066
- splitAtom(selectAtom(notebookAtom, (e) => e.cellIds.inOrderIds.map((r) => e.cellData[r]))), atom((e) => e(notebookAtom).cellRuntime), atom((e) => notebookIsRunning(e(notebookAtom))), atom((e) => notebookQueueOrRunningCount(e(notebookAtom))), atom((e) => e(notebookAtom).cellIds.colLength), atom((e) => e(notebookAtom).cellIds.idLength > 0), atom((e) => e(notebookAtom).cellIds.getColumnIds());
37116
+ splitAtom(selectAtom(notebookAtom, (e) => e.cellIds.inOrderIds.map((r) => e.cellData[r]))), atom((e) => e(notebookAtom).cellRuntime), atom((e) => notebookIsRunning(e(notebookAtom))), atom((e) => {
37117
+ let { cellRuntime: r } = e(notebookAtom);
37118
+ return Object.entries(r).every(([e2, r2]) => r2.status !== "running" || e2 === "__scratch__");
37119
+ }), atom((e) => notebookQueueOrRunningCount(e(notebookAtom))), atom((e) => e(notebookAtom).cellIds.colLength), atom((e) => e(notebookAtom).cellIds.idLength > 0), atom((e) => e(notebookAtom).cellIds.getColumnIds());
37067
37120
  const cellDataAtom = atomFamily((e) => atom((r) => r(notebookAtom).cellData[e]));
37068
37121
  var cellRuntimeAtom = atomFamily((e) => atom((r) => r(notebookAtom).cellRuntime[e]));
37069
37122
  const cellHandleAtom = atomFamily((e) => atom((r) => r(notebookAtom).cellHandles[e]));
@@ -56358,7 +56411,7 @@ Database schema: ${c}`), (_a4 = r2.aiFix) == null ? void 0 : _a4.setAiCompletion
56358
56411
  hasConsoleOutput: (v == null ? void 0 : v.consoleOutputs) != null
56359
56412
  };
56360
56413
  }
56361
- const LazyAnyLanguageCodeMirror = (0, import_react.lazy)(() => import("./any-language-editor-DIUWKyeN.js"));
56414
+ const LazyAnyLanguageCodeMirror = (0, import_react.lazy)(() => import("./any-language-editor-DlsjUw_l.js"));
56362
56415
  var import_compiler_runtime$117 = require_compiler_runtime(), extensions = [
56363
56416
  EditorView.lineWrapping
56364
56417
  ];
@@ -70724,7 +70777,7 @@ Image URL: ${r.imageUrl}`)), contextToXml({
70724
70777
  return Logger.warn("Failed to get version from mount config"), null;
70725
70778
  }
70726
70779
  }
70727
- const marimoVersionAtom = atom(getVersionFromMountConfig() || "0.21.1-dev18"), showCodeInRunModeAtom = atom(true);
70780
+ const marimoVersionAtom = atom(getVersionFromMountConfig() || "0.21.1-dev21"), showCodeInRunModeAtom = atom(true);
70728
70781
  atom(null);
70729
70782
  var import_compiler_runtime$89 = require_compiler_runtime();
70730
70783
  function useKeydownOnElement(e, r) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.21.1-dev18",
3
+ "version": "0.21.1-dev21",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -5,6 +5,7 @@ import { HourglassIcon, LockIcon, UnlinkIcon } from "lucide-react";
5
5
  import React from "react";
6
6
  import { Tooltip } from "@/components/ui/tooltip";
7
7
  import { notebookScrollToRunning } from "@/core/cells/actions";
8
+ import { onlyScratchpadIsRunningAtom } from "@/core/cells/cells";
8
9
  import { viewStateAtom } from "@/core/mode";
9
10
  import { type ConnectionStatus, WebSocketState } from "@/core/websocket/types";
10
11
  import { cn } from "@/utils/cn";
@@ -52,17 +53,24 @@ const LockedIcon = () => (
52
53
  </Tooltip>
53
54
  );
54
55
 
55
- const RunningIcon = () => (
56
- <Tooltip content="Jump to running cell" side="right">
57
- <div
58
- className={topLeftStatus}
59
- data-testid="loading-indicator"
60
- onClick={notebookScrollToRunning}
61
- >
62
- <HourglassIcon className="running-app-icon" size={30} strokeWidth={1} />
63
- </div>
64
- </Tooltip>
65
- );
56
+ const RunningIcon = () => {
57
+ const scratchpadOnly = useAtomValue(onlyScratchpadIsRunningAtom);
58
+ const tooltip = scratchpadOnly
59
+ ? "Scratchpad is running"
60
+ : "Jump to running cell";
61
+
62
+ return (
63
+ <Tooltip content={tooltip} side="right">
64
+ <div
65
+ className={topLeftStatus}
66
+ data-testid="loading-indicator"
67
+ onClick={scratchpadOnly ? undefined : notebookScrollToRunning}
68
+ >
69
+ <HourglassIcon className="running-app-icon" size={30} strokeWidth={1} />
70
+ </div>
71
+ </Tooltip>
72
+ );
73
+ };
66
74
 
67
75
  const NoiseBackground = () => (
68
76
  <>
@@ -1640,6 +1640,12 @@ export const cellsRuntimeAtom = atom((get) => get(notebookAtom).cellRuntime);
1640
1640
  export const notebookIsRunningAtom = atom((get) =>
1641
1641
  notebookIsRunning(get(notebookAtom)),
1642
1642
  );
1643
+ export const onlyScratchpadIsRunningAtom = atom((get) => {
1644
+ const { cellRuntime } = get(notebookAtom);
1645
+ return Object.entries(cellRuntime).every(
1646
+ ([id, rt]) => rt.status !== "running" || id === SCRATCH_CELL_ID,
1647
+ );
1648
+ });
1643
1649
  export const notebookQueuedOrRunningCountAtom = atom((get) =>
1644
1650
  notebookQueueOrRunningCount(get(notebookAtom)),
1645
1651
  );
@@ -11,6 +11,7 @@ export function notebookIsRunning(state: NotebookState) {
11
11
  (cell) => cell.status === "running",
12
12
  );
13
13
  }
14
+
14
15
  export function notebookQueueOrRunningCount(state: NotebookState) {
15
16
  return Object.values(state.cellRuntime).filter(
16
17
  (cell) => cell.status === "running" || cell.status === "queued",
@@ -3,7 +3,11 @@
3
3
  import type { EditorState } from "@codemirror/state";
4
4
  import type { EditorView } from "@codemirror/view";
5
5
  import { replaceEditorContent } from "../replace-editor-content";
6
- import { languageAdapterState } from "./extension";
6
+ import {
7
+ languageAdapterFromCode,
8
+ languageAdapterState,
9
+ switchLanguage,
10
+ } from "./extension";
7
11
  import { languageMetadataField } from "./metadata";
8
12
 
9
13
  /**
@@ -35,6 +39,17 @@ export function updateEditorCodeFromPython(
35
39
  editor: EditorView,
36
40
  pythonCode: string,
37
41
  ): string {
42
+ const currentAdapter = editor.state.field(languageAdapterState);
43
+ const correctAdapter = languageAdapterFromCode(pythonCode);
44
+
45
+ // If the language type changed (e.g., markdown → python), switch adapters
46
+ if (correctAdapter.type !== currentAdapter.type) {
47
+ switchLanguage(editor, {
48
+ language: correctAdapter.type,
49
+ keepCodeAsIs: true,
50
+ });
51
+ }
52
+
38
53
  const languageAdapter = editor.state.field(languageAdapterState);
39
54
  const [code] = languageAdapter.transformIn(pythonCode);
40
55
  // Use replaceEditorContent which preserves cursor position when focused