@marimo-team/frontend 0.24.3-dev36 → 0.24.3-dev39
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/assets/{ConnectedDataExplorerComponent-CsA_EqMs.js → ConnectedDataExplorerComponent-B52ZeTyE.js} +1 -1
- package/dist/assets/{LazyAnyLanguageCodeMirror-jAV-LD6v.js → LazyAnyLanguageCodeMirror-DLXghRUF.js} +2 -2
- package/dist/assets/{RunButton-Bo4tYCqW.js → RunButton-BQonXEus.js} +7 -7
- package/dist/assets/{abnfDiagram-VCTEODGH-Dpe20TKk.js → abnfDiagram-VCTEODGH-DAeh_Fhj.js} +1 -1
- package/dist/assets/{add-cell-with-ai-CkjbbM3K.js → add-cell-with-ai-BqPNrEkg.js} +10 -10
- package/dist/assets/{agent-panel-CJ__bZ2U.js → agent-panel-0QpsWJ6N.js} +4 -4
- package/dist/assets/{ai-model-dropdown-CFjRFxPs.js → ai-model-dropdown-JyOkbRgs.js} +2 -2
- package/dist/assets/{any-language-editor-CVvssaI-.js → any-language-editor-DktznOiF.js} +1 -1
- package/dist/assets/app-config-button-hlzBggjV.js +1 -0
- package/dist/assets/{architectureDiagram-5GKGNRK7-LjPvmKXz.js → architectureDiagram-5GKGNRK7-CLV_t53p.js} +1 -1
- package/dist/assets/{blockDiagram-I7D4REHJ-Dcw3YZc7.js → blockDiagram-I7D4REHJ-4NgsF8dG.js} +1 -1
- package/dist/assets/cache-panel-JD-3Sv8N.js +1 -0
- package/dist/assets/{cells-DcI93as7.js → cells-CP3hwqVX.js} +5 -5
- package/dist/assets/{chat-display-BxoFsvsk.js → chat-display-f6K2vP1M.js} +1 -1
- package/dist/assets/{chat-panel-OPXY9xqa.js → chat-panel-CPSz0Ygy.js} +3 -3
- package/dist/assets/{chat-ui-B7Op0m5y.js → chat-ui-DJskwz2p.js} +3 -3
- package/dist/assets/{chunk-IMKFNOWR-BhKJw_u0.js → chunk-IMKFNOWR-gOOmxUZk.js} +1 -1
- package/dist/assets/{chunk-SHT3W25Y-BLq6CG7S.js → chunk-SHT3W25Y-Vz0rwhW1.js} +1 -1
- package/dist/assets/{chunk-SVP7TREG-DYlo9xS8.js → chunk-SVP7TREG-DXVPjbAe.js} +1 -1
- package/dist/assets/{chunk-TICWLB2K-D5DDJ9ap.js → chunk-TICWLB2K-DwIBziwV.js} +1 -1
- package/dist/assets/{classDiagram-ZZMXUADV-Cpgr9tEc.js → classDiagram-ZZMXUADV-CyUk9nSP.js} +1 -1
- package/dist/assets/{classDiagram-v2-VYDZK3BY-Cpgr9tEc.js → classDiagram-v2-VYDZK3BY-CyUk9nSP.js} +1 -1
- package/dist/assets/{command-palette-BBhAYPL7.js → command-palette-B8zE6Ssx.js} +1 -1
- package/dist/assets/{common-DGrIhswR.js → common-CHWS0pGT.js} +1 -1
- package/dist/assets/{components-BzThHPL8.js → components-B8fYemsk.js} +1 -1
- package/dist/assets/{components-XxbsL-NL.js → components-v8nHOj_y.js} +1 -1
- package/dist/assets/config-CBLBAU5c.js +1 -0
- package/dist/assets/{cynefinDiagram-5FMLGOSQ-cA8HNBWT.js → cynefinDiagram-5FMLGOSQ-DgdyjbQj.js} +1 -1
- package/dist/assets/{dagre-Cgh-CozI.js → dagre-CPZ1FUhr.js} +1 -1
- package/dist/assets/{dagre-GXQ25YYZ-DMu-4gaX.js → dagre-GXQ25YYZ-D-zMjnRl.js} +1 -1
- package/dist/assets/{data-grid-overlay-editor-o8dOZGaO.js → data-grid-overlay-editor-CFK1KT2V.js} +1 -1
- package/dist/assets/{dependency-graph-panel-DSfkNvTe.js → dependency-graph-panel-D_AqnRMs.js} +3 -3
- package/dist/assets/{diagram-S7CK7UJ4-0g042cjW.js → diagram-S7CK7UJ4-DgflUEq5.js} +1 -1
- package/dist/assets/{diagram-UQ7AKVKN-CoeYBFyV.js → diagram-UQ7AKVKN-m3R2UDJM.js} +1 -1
- package/dist/assets/{diagram-VX7I27RA-CIbkeHtW.js → diagram-VX7I27RA-Blh2o8ik.js} +1 -1
- package/dist/assets/{diagram-Z3DM3KII-VNvdSBDs.js → diagram-Z3DM3KII-C4PcKTD6.js} +1 -1
- package/dist/assets/{documentation-panel-BYssFEdu.js → documentation-panel-CoSoUakB.js} +1 -1
- package/dist/assets/{ebnfDiagram-PWID7BFC-gn-sVFpd.js → ebnfDiagram-PWID7BFC-BGtaPv5f.js} +1 -1
- package/dist/assets/edit-page-Qqpz6lsF.js +184 -0
- package/dist/assets/{erDiagram-RLTQ6QDP-CHEeDG3E.js → erDiagram-RLTQ6QDP-D8JVfIur.js} +1 -1
- package/dist/assets/{error-panel-BEyUxPKv.js → error-panel-CdqCDhu4.js} +1 -1
- package/dist/assets/{file-explorer-panel-BkidiqtU.js → file-explorer-panel-DcWEU9mt.js} +1 -1
- package/dist/assets/{file-name-input-DRW2aJnO.js → file-name-input-BQw4Jo-i.js} +1 -1
- package/dist/assets/{flowDiagram-HODETNUW-juSojTPv.js → flowDiagram-HODETNUW-DMus6jv_.js} +1 -1
- package/dist/assets/{gallery-page-C8KW0aF4.js → gallery-page-_mH_5ChL.js} +1 -1
- package/dist/assets/{glide-data-editor-C-EXft2Q.js → glide-data-editor-CFcsGnit.js} +4 -4
- package/dist/assets/{graphlib-rnp4xs81.js → graphlib-Sg3tw7ov.js} +1 -1
- package/dist/assets/has-DXmEv5FL.js +1 -0
- package/dist/assets/{home-page-CG6vbN4B.js → home-page-hKIN8akr.js} +2 -2
- package/dist/assets/index-B8OSEJVD.css +2 -0
- package/dist/assets/index-qY3lu9r4.js +62 -0
- package/dist/assets/{infoDiagram-27XIBGKW-C4VdBugr.js → infoDiagram-27XIBGKW-DYsYx_PP.js} +1 -1
- package/dist/assets/{ishikawaDiagram-5VMMS53U-BS-QMwse.js → ishikawaDiagram-5VMMS53U-D1Rpw_lT.js} +1 -1
- package/dist/assets/{kanban-definition-UXKFOSKX-HVONQMlk.js → kanban-definition-UXKFOSKX-CGxkIydR.js} +1 -1
- package/dist/assets/{logs-panel-BNeI_Aah.js → logs-panel-C4k8cMGx.js} +1 -1
- package/dist/assets/{mermaid-LovyOmSB.js → mermaid-BLxkTwc2.js} +4 -4
- package/dist/assets/{mindmap-definition-YA3MSWOX-DyBY39cg.js → mindmap-definition-YA3MSWOX-BiuGfVWP.js} +1 -1
- package/dist/assets/{number-overlay-editor-CwRpjoZm.js → number-overlay-editor-Ck2sCaO7.js} +1 -1
- package/dist/assets/{outline-panel-bDklL4uf.js → outline-panel-Z6FAHcVy.js} +1 -1
- package/dist/assets/packages-panel-CgL87fcO.js +1 -0
- package/dist/assets/panels-BSvT-tNo.js +33 -0
- package/dist/assets/{pegDiagram-XKGWAZYB-kQLDO-kO.js → pegDiagram-XKGWAZYB-Ci7mDvEz.js} +1 -1
- package/dist/assets/{pieDiagram-E7YTZNPT-DJsFtYCp.js → pieDiagram-E7YTZNPT-DZbp0Icu.js} +1 -1
- package/dist/assets/{process-output-CVZMao0e.js → process-output-COWXLjOr.js} +1 -1
- package/dist/assets/{railroadDiagram-O6MQD6OU-Bcf0CSqH.js → railroadDiagram-O6MQD6OU-CzXIAsPx.js} +1 -1
- package/dist/assets/{requirementDiagram-BXWQKSXE-AGcJcQbq.js → requirementDiagram-BXWQKSXE-DsIrXWi5.js} +1 -1
- package/dist/assets/{reveal-component-Dx_L-cIu.js → reveal-component-CnW6op6f.js} +3 -3
- package/dist/assets/run-page-B_JOrxWI.js +1 -0
- package/dist/assets/{scratchpad-panel-DfvfNJDq.js → scratchpad-panel-DktgeGw9.js} +1 -1
- package/dist/assets/{secrets-panel-CZbY8wgN.js → secrets-panel-Di8040gJ.js} +1 -1
- package/dist/assets/{sequenceDiagram-WJ2MYXX4-Cokf6L0R.js → sequenceDiagram-WJ2MYXX4-YEyNvwCq.js} +1 -1
- package/dist/assets/{session-panel-Cmsewdss.js → session-panel-FmN2Ix-x.js} +1 -1
- package/dist/assets/{snippets-panel-B_XreO-C.js → snippets-panel-BmXCx6yt.js} +1 -1
- package/dist/assets/{stateDiagram-D77RDMKH-CdkNCpaH.js → stateDiagram-D77RDMKH-B3Ja9Vk7.js} +1 -1
- package/dist/assets/{stateDiagram-v2-MP3YSRHH-CpudHHc4.js → stateDiagram-v2-MP3YSRHH-Bn7tPa_c.js} +1 -1
- package/dist/assets/{swimlanes-42K2YHIH-_8ELJqVB.js → swimlanes-42K2YHIH-DTgRQfmF.js} +1 -1
- package/dist/assets/{swimlanesDiagram-VR7AAH4N-qd1AHOJZ.js → swimlanesDiagram-VR7AAH4N-DKJ2qI6J.js} +1 -1
- package/dist/assets/{swiper-component-DY4M2PJo.js → swiper-component-CYrf6kVu.js} +1 -1
- package/dist/assets/{terminal-CTP4KOwN.js → terminal-CBss1CM1.js} +2 -2
- package/dist/assets/{timeline-definition-24CTP7MA-donBeXb2.js → timeline-definition-24CTP7MA-CKo5fHyB.js} +1 -1
- package/dist/assets/{tracing-DgHfkjPY.js → tracing-BBufraD6.js} +1 -1
- package/dist/assets/{tracing-panel-Qiu_S5kw.js → tracing-panel-lUoyxh7t.js} +2 -2
- package/dist/assets/{useCellActionButton-BCWgCI24.js → useCellActionButton-VJCYmjUy.js} +1 -1
- package/dist/assets/{vega-component-CC6LYLy6.js → vega-component-BUKpKmrE.js} +1 -1
- package/dist/assets/{vega-embed-container-CMoER1M0.js → vega-embed-container-BgSrb2ci.js} +1 -1
- package/dist/assets/{vennDiagram-4TSXK5OY-BgCWyFeF.js → vennDiagram-4TSXK5OY-CA_b78pk.js} +1 -1
- package/dist/assets/{wardleyDiagram-VM6X3IG4-rkxibRUc.js → wardleyDiagram-VM6X3IG4-CT2UYDxA.js} +1 -1
- package/dist/assets/{xychartDiagram-S5SC5T6Z-Bfs-6MBb.js → xychartDiagram-S5SC5T6Z-BOvLySSM.js} +1 -1
- package/dist/index.html +5 -5
- package/package.json +1 -1
- package/src/__mocks__/requests.ts +7 -0
- package/src/components/editor/alerts/connecting-alert.tsx +1 -66
- package/src/components/editor/alerts/connection-notice.tsx +140 -0
- package/src/components/editor/app-container.tsx +9 -3
- package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +114 -7
- package/src/components/editor/chrome/panels/__tests__/sandbox-recovery.test.tsx +165 -0
- package/src/components/editor/chrome/panels/packages-panel.tsx +93 -166
- package/src/components/editor/chrome/panels/sandbox-controller.tsx +106 -0
- package/src/components/editor/chrome/panels/sandbox-panel.tsx +173 -0
- package/src/components/editor/chrome/wrapper/footer-items/backend-status.tsx +3 -1
- package/src/components/editor/header/__tests__/status.test.tsx +8 -20
- package/src/components/editor/header/status.tsx +5 -3
- package/src/components/editor/renderers/cell-array.tsx +1 -5
- package/src/core/MarimoApp.tsx +0 -2
- package/src/core/edit-app.tsx +8 -5
- package/src/core/errors/state.ts +1 -2
- package/src/core/islands/bootstrap.ts +1 -0
- package/src/core/islands/bridge.ts +3 -0
- package/src/core/network/connection-notice.ts +84 -0
- package/src/core/network/requests-lazy.ts +3 -0
- package/src/core/network/requests-network.ts +12 -0
- package/src/core/network/requests-static.ts +3 -0
- package/src/core/network/requests-toasting.tsx +3 -0
- package/src/core/network/resolve.ts +2 -1
- package/src/core/network/types.ts +7 -0
- package/src/core/packages/__tests__/usePackageAction.test.tsx +129 -0
- package/src/core/packages/__tests__/useSandboxController.test.tsx +165 -0
- package/src/core/packages/package-data.ts +35 -0
- package/src/core/packages/sandbox-state.ts +15 -0
- package/src/core/packages/toast-components.tsx +11 -0
- package/src/core/packages/useInstallPackage.ts +1 -1
- package/src/core/packages/usePackageAction.ts +51 -0
- package/src/core/packages/usePackageDependencies.ts +22 -0
- package/src/core/packages/useSandboxController.ts +188 -0
- package/src/core/run-app.tsx +2 -0
- package/src/core/wasm/bridge.ts +11 -0
- package/src/core/websocket/__tests__/useMarimoKernelConnection.hook.test.tsx +212 -2
- package/src/core/websocket/types.ts +11 -1
- package/src/core/websocket/useMarimoKernelConnection.tsx +43 -8
- package/src/stories/sandbox.stories.tsx +308 -0
- package/dist/assets/app-config-button-BgRYYpoH.js +0 -1
- package/dist/assets/cache-panel-DP6AuApU.js +0 -1
- package/dist/assets/config-D4PQ0ExB.js +0 -1
- package/dist/assets/edit-page-B5T44oKE.js +0 -184
- package/dist/assets/has-BPYf0PV2.js +0 -1
- package/dist/assets/index-Bit3pmfj.css +0 -2
- package/dist/assets/index-D3ydSabW.js +0 -62
- package/dist/assets/packages-panel-BvnEJCqo.js +0 -1
- package/dist/assets/panels-DvYa8VJO.js +0 -33
- package/dist/assets/run-page-BIX2SnOg.js +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
|
+
import { invalidatePackageData } from "@/core/packages/package-data";
|
|
3
4
|
import { useAtom, useAtomValue, useSetAtom } from "jotai";
|
|
4
5
|
import { useRef } from "react";
|
|
5
6
|
import { useErrorBoundary } from "react-error-boundary";
|
|
@@ -240,7 +241,15 @@ export function useMarimoKernelConnection(opts: {
|
|
|
240
241
|
case "reload":
|
|
241
242
|
reloadSafe();
|
|
242
243
|
return;
|
|
244
|
+
case "startup-progress":
|
|
245
|
+
setConnection({
|
|
246
|
+
state: WebSocketState.CONNECTING,
|
|
247
|
+
phase: msg.data.phase,
|
|
248
|
+
});
|
|
249
|
+
return;
|
|
243
250
|
case "kernel-ready": {
|
|
251
|
+
setKernelStartupError(null);
|
|
252
|
+
setConnection({ state: WebSocketState.OPEN });
|
|
244
253
|
setInitialRunCompleted(
|
|
245
254
|
Boolean(msg.data.resumed || msg.data.auto_instantiated),
|
|
246
255
|
);
|
|
@@ -363,6 +372,16 @@ export function useMarimoKernelConnection(opts: {
|
|
|
363
372
|
});
|
|
364
373
|
return;
|
|
365
374
|
case "installing-package-alert":
|
|
375
|
+
if (
|
|
376
|
+
msg.data.source !== "server" &&
|
|
377
|
+
msg.data.log_status !== "append" &&
|
|
378
|
+
msg.data.log_status !== "start" &&
|
|
379
|
+
Object.values(msg.data.packages).some(
|
|
380
|
+
(status) => status === "installed" || status === "restart-required",
|
|
381
|
+
)
|
|
382
|
+
) {
|
|
383
|
+
invalidatePackageData();
|
|
384
|
+
}
|
|
366
385
|
addPackageAlert({
|
|
367
386
|
...msg.data,
|
|
368
387
|
kind: "installing",
|
|
@@ -439,6 +458,8 @@ export function useMarimoKernelConnection(opts: {
|
|
|
439
458
|
return;
|
|
440
459
|
|
|
441
460
|
case "reconnected":
|
|
461
|
+
setKernelStartupError(null);
|
|
462
|
+
setConnection({ state: WebSocketState.OPEN });
|
|
442
463
|
return;
|
|
443
464
|
|
|
444
465
|
case "focus-cell":
|
|
@@ -482,6 +503,7 @@ export function useMarimoKernelConnection(opts: {
|
|
|
482
503
|
return;
|
|
483
504
|
}
|
|
484
505
|
shouldTryReconnecting.current = true;
|
|
506
|
+
setKernelStartupError(null);
|
|
485
507
|
setConnection({ state: WebSocketState.CONNECTING });
|
|
486
508
|
const healthy = await runtimeManager.reconcileFromHealth();
|
|
487
509
|
if (!healthy) {
|
|
@@ -513,17 +535,11 @@ export function useMarimoKernelConnection(opts: {
|
|
|
513
535
|
headers: () => runtimeManager.headers(),
|
|
514
536
|
|
|
515
537
|
/**
|
|
516
|
-
*
|
|
538
|
+
* The transport is open; kernel-ready establishes session readiness.
|
|
517
539
|
*/
|
|
518
540
|
onOpen: async () => {
|
|
519
541
|
// If we are open, we can reset our reconnecting flag.
|
|
520
542
|
shouldTryReconnecting.current = true;
|
|
521
|
-
|
|
522
|
-
// DO NOT COMMIT THIS UNCOMMENTED
|
|
523
|
-
// Uncomment to emulate a slow connection
|
|
524
|
-
// await new Promise((resolve) => setTimeout(resolve, 10_000));
|
|
525
|
-
|
|
526
|
-
setConnection({ state: WebSocketState.OPEN });
|
|
527
543
|
},
|
|
528
544
|
|
|
529
545
|
/**
|
|
@@ -565,7 +581,26 @@ export function useMarimoKernelConnection(opts: {
|
|
|
565
581
|
onClose: (e) => {
|
|
566
582
|
Logger.warn("WebSocket closed", e.code, e.reason);
|
|
567
583
|
const decision = classifyCloseEvent(e);
|
|
568
|
-
setConnection(
|
|
584
|
+
setConnection((previous) => {
|
|
585
|
+
const status = decision.status;
|
|
586
|
+
if (
|
|
587
|
+
status.state === WebSocketState.CLOSED &&
|
|
588
|
+
status.code === WebSocketClosedReason.KERNEL_STARTUP_ERROR &&
|
|
589
|
+
(previous.state === WebSocketState.CONNECTING ||
|
|
590
|
+
previous.state === WebSocketState.CLOSED)
|
|
591
|
+
) {
|
|
592
|
+
return { ...status, phase: previous.phase };
|
|
593
|
+
}
|
|
594
|
+
if (
|
|
595
|
+
status.state === WebSocketState.CONNECTING &&
|
|
596
|
+
(previous.state === WebSocketState.OPEN ||
|
|
597
|
+
(previous.state === WebSocketState.CONNECTING &&
|
|
598
|
+
previous.phase === "reconnecting"))
|
|
599
|
+
) {
|
|
600
|
+
return { ...status, phase: "reconnecting" };
|
|
601
|
+
}
|
|
602
|
+
return status;
|
|
603
|
+
});
|
|
569
604
|
if (decision.kind === "terminal" && decision.closeTransport) {
|
|
570
605
|
ws.close(); // close to prevent reconnecting
|
|
571
606
|
return;
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
3
|
+
import { createStore, Provider, useAtomValue } from "jotai";
|
|
4
|
+
import { useEffect, useRef, useState } from "react";
|
|
5
|
+
import { ConnectionNotice } from "@/components/editor/alerts/connection-notice";
|
|
6
|
+
import {
|
|
7
|
+
SandboxFooter,
|
|
8
|
+
SandboxStartupPanel,
|
|
9
|
+
} from "@/components/editor/chrome/panels/sandbox-panel";
|
|
10
|
+
import { SandboxController } from "@/components/editor/chrome/panels/sandbox-controller";
|
|
11
|
+
import { chromeAtom } from "@/components/editor/chrome/state";
|
|
12
|
+
import { Cell } from "@/components/editor/notebook-cell";
|
|
13
|
+
import { VerticalLayoutWrapper } from "@/components/editor/renderers/vertical-layout/vertical-layout-wrapper";
|
|
14
|
+
import {
|
|
15
|
+
createNotebookActions,
|
|
16
|
+
notebookAtom,
|
|
17
|
+
notebookReducer,
|
|
18
|
+
} from "@/core/cells/cells";
|
|
19
|
+
import { userConfigAtom } from "@/core/config/config";
|
|
20
|
+
import {
|
|
21
|
+
AppConfigSchema,
|
|
22
|
+
defaultUserConfig,
|
|
23
|
+
} from "@/core/config/config-schema";
|
|
24
|
+
import { kernelStartupErrorAtom } from "@/core/errors/state";
|
|
25
|
+
import { connectionAtom } from "@/core/network/connection";
|
|
26
|
+
import { requestClientAtom } from "@/core/network/requests";
|
|
27
|
+
import { createStaticRequests } from "@/core/network/requests-static";
|
|
28
|
+
import {
|
|
29
|
+
sandboxActionsAtom,
|
|
30
|
+
sandboxAtom,
|
|
31
|
+
sandboxSyncAtom,
|
|
32
|
+
} from "@/core/packages/sandbox-state";
|
|
33
|
+
import { filenameAtom } from "@/core/saving/file-state";
|
|
34
|
+
import { WebSocketClosedReason, WebSocketState } from "@/core/websocket/types";
|
|
35
|
+
import { HTTPError } from "@/utils/errors";
|
|
36
|
+
|
|
37
|
+
const manifest = `requires-python = ">=3.13"
|
|
38
|
+
dependencies = ["marimo", "polars", "rich==999.0.0"]
|
|
39
|
+
|
|
40
|
+
[tool.uv]
|
|
41
|
+
index-url = "https://pypi.org/simple"
|
|
42
|
+
|
|
43
|
+
[tool.notebook]
|
|
44
|
+
description = "Explore bike trips"
|
|
45
|
+
`;
|
|
46
|
+
const resolutionError = `No solution found when resolving dependencies:
|
|
47
|
+
Because there is no version of rich==999.0.0 and your script depends
|
|
48
|
+
on rich==999.0.0, your script's requirements are unsatisfiable.`;
|
|
49
|
+
|
|
50
|
+
interface Props {
|
|
51
|
+
surface: "notebook" | "packages" | "manifest";
|
|
52
|
+
phase:
|
|
53
|
+
| "preparing"
|
|
54
|
+
| "starting"
|
|
55
|
+
| "failed"
|
|
56
|
+
| "ready"
|
|
57
|
+
| "syncing"
|
|
58
|
+
| "sync-failed";
|
|
59
|
+
existingCells: boolean;
|
|
60
|
+
backend: "uv" | "pixi";
|
|
61
|
+
saveResult: "success" | "failure" | "stale";
|
|
62
|
+
theme: "light" | "dark";
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function OpenManifest() {
|
|
66
|
+
const actions = useAtomValue(sandboxActionsAtom);
|
|
67
|
+
const opened = useRef(false);
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (actions && !opened.current) {
|
|
70
|
+
opened.current = true;
|
|
71
|
+
void actions.editManifest();
|
|
72
|
+
}
|
|
73
|
+
}, [actions]);
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function SandboxStory(props: Props) {
|
|
78
|
+
const [store] = useState(() => {
|
|
79
|
+
const state = createStore();
|
|
80
|
+
let currentManifest =
|
|
81
|
+
props.phase === "failed"
|
|
82
|
+
? manifest
|
|
83
|
+
: manifest.replace("rich==999.0.0", "rich>=13.0.0");
|
|
84
|
+
const config = defaultUserConfig();
|
|
85
|
+
state.set(userConfigAtom, {
|
|
86
|
+
...config,
|
|
87
|
+
display: { ...config.display, theme: props.theme },
|
|
88
|
+
});
|
|
89
|
+
state.set(filenameAtom, "bike_trips.py");
|
|
90
|
+
state.set(sandboxAtom, {
|
|
91
|
+
backend: props.backend,
|
|
92
|
+
manifest: currentManifest,
|
|
93
|
+
filename: "bike_trips.py",
|
|
94
|
+
});
|
|
95
|
+
state.set(chromeAtom, {
|
|
96
|
+
selectedPanel: "packages",
|
|
97
|
+
isSidebarOpen: props.surface !== "notebook",
|
|
98
|
+
isDeveloperPanelOpen: false,
|
|
99
|
+
selectedDeveloperPanelTab: "errors",
|
|
100
|
+
});
|
|
101
|
+
state.set(
|
|
102
|
+
connectionAtom,
|
|
103
|
+
props.phase === "preparing" || props.phase === "starting"
|
|
104
|
+
? {
|
|
105
|
+
state: WebSocketState.CONNECTING,
|
|
106
|
+
phase:
|
|
107
|
+
props.phase === "preparing"
|
|
108
|
+
? "preparing-environment"
|
|
109
|
+
: "starting-kernel",
|
|
110
|
+
}
|
|
111
|
+
: props.phase === "failed"
|
|
112
|
+
? {
|
|
113
|
+
state: WebSocketState.CLOSED,
|
|
114
|
+
code: WebSocketClosedReason.KERNEL_STARTUP_ERROR,
|
|
115
|
+
reason: "Kernel startup failed",
|
|
116
|
+
phase: "preparing-environment",
|
|
117
|
+
}
|
|
118
|
+
: { state: WebSocketState.OPEN },
|
|
119
|
+
);
|
|
120
|
+
state.set(
|
|
121
|
+
kernelStartupErrorAtom,
|
|
122
|
+
props.phase === "failed" ? resolutionError : null,
|
|
123
|
+
);
|
|
124
|
+
state.set(sandboxSyncAtom, {
|
|
125
|
+
pending: props.phase === "syncing",
|
|
126
|
+
error: props.phase === "sync-failed" ? resolutionError : null,
|
|
127
|
+
});
|
|
128
|
+
if (props.existingCells) {
|
|
129
|
+
const actions = createNotebookActions((action) =>
|
|
130
|
+
state.set(notebookAtom, (value) => notebookReducer(value, action)),
|
|
131
|
+
);
|
|
132
|
+
actions.createNewCell({
|
|
133
|
+
cellId: "__end__",
|
|
134
|
+
before: false,
|
|
135
|
+
code: 'import polars as pl\n\ntrips = pl.read_csv("bike_trips.csv")\ntrips.head()',
|
|
136
|
+
autoFocus: false,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
state.set(requestClientAtom, {
|
|
140
|
+
...createStaticRequests(),
|
|
141
|
+
getSandbox: async () => ({
|
|
142
|
+
backend: props.backend,
|
|
143
|
+
manifest: currentManifest,
|
|
144
|
+
filename: "bike_trips.py",
|
|
145
|
+
}),
|
|
146
|
+
updateManifest: async ({ contents }) => {
|
|
147
|
+
if (props.saveResult === "stale") {
|
|
148
|
+
throw new HTTPError(
|
|
149
|
+
409,
|
|
150
|
+
"The manifest changed on disk. Reopen it before saving.",
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
currentManifest = contents;
|
|
154
|
+
return {
|
|
155
|
+
backend: props.backend,
|
|
156
|
+
manifest: currentManifest,
|
|
157
|
+
filename: "bike_trips.py",
|
|
158
|
+
};
|
|
159
|
+
},
|
|
160
|
+
syncSandbox: async () => {
|
|
161
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
162
|
+
if (props.saveResult === "failure") {
|
|
163
|
+
return {
|
|
164
|
+
success: false,
|
|
165
|
+
error:
|
|
166
|
+
"Failed to download rich from https://pypi.org/simple/rich/\n Request failed after 3 retries: connection timed out",
|
|
167
|
+
restartRequired: false,
|
|
168
|
+
reconnect: false,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
state.set(connectionAtom, { state: WebSocketState.OPEN });
|
|
172
|
+
state.set(kernelStartupErrorAtom, null);
|
|
173
|
+
return {
|
|
174
|
+
success: true,
|
|
175
|
+
error: null,
|
|
176
|
+
restartRequired: false,
|
|
177
|
+
reconnect: false,
|
|
178
|
+
};
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
return state;
|
|
182
|
+
});
|
|
183
|
+
const appConfig = AppConfigSchema.parse({ width: "full" });
|
|
184
|
+
const reconnect = async () => {
|
|
185
|
+
store.set(connectionAtom, { state: WebSocketState.OPEN });
|
|
186
|
+
};
|
|
187
|
+
return (
|
|
188
|
+
<Provider store={store}>
|
|
189
|
+
<SandboxController onReconnect={reconnect} />
|
|
190
|
+
{props.surface === "manifest" && <OpenManifest />}
|
|
191
|
+
<div
|
|
192
|
+
data-testid="sandbox-story"
|
|
193
|
+
className="bg-background text-foreground"
|
|
194
|
+
style={{
|
|
195
|
+
width: props.surface === "notebook" ? 820 : 400,
|
|
196
|
+
}}
|
|
197
|
+
>
|
|
198
|
+
{props.surface === "notebook" && (
|
|
199
|
+
<>
|
|
200
|
+
<ConnectionNotice appConfig={appConfig} onRetry={reconnect} />
|
|
201
|
+
{store.get(notebookAtom).cellIds.inOrderIds.map((cellId) => (
|
|
202
|
+
<VerticalLayoutWrapper key={cellId} appConfig={appConfig}>
|
|
203
|
+
<Cell
|
|
204
|
+
cellId={cellId}
|
|
205
|
+
theme={props.theme}
|
|
206
|
+
mode="edit"
|
|
207
|
+
showPlaceholder={false}
|
|
208
|
+
canDelete={true}
|
|
209
|
+
isCollapsed={false}
|
|
210
|
+
collapseCount={0}
|
|
211
|
+
canMoveX={false}
|
|
212
|
+
userConfig={store.get(userConfigAtom)}
|
|
213
|
+
/>
|
|
214
|
+
</VerticalLayoutWrapper>
|
|
215
|
+
))}
|
|
216
|
+
</>
|
|
217
|
+
)}
|
|
218
|
+
{props.surface === "packages" &&
|
|
219
|
+
(props.phase === "failed" ||
|
|
220
|
+
props.phase === "sync-failed" ||
|
|
221
|
+
props.phase === "preparing" ? (
|
|
222
|
+
<SandboxStartupPanel />
|
|
223
|
+
) : (
|
|
224
|
+
<SandboxFooter />
|
|
225
|
+
))}
|
|
226
|
+
</div>
|
|
227
|
+
</Provider>
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const meta = {
|
|
232
|
+
title: "Sandbox/States",
|
|
233
|
+
component: SandboxStory,
|
|
234
|
+
parameters: { layout: "centered" },
|
|
235
|
+
args: {
|
|
236
|
+
surface: "notebook",
|
|
237
|
+
phase: "preparing",
|
|
238
|
+
existingCells: true,
|
|
239
|
+
backend: "uv",
|
|
240
|
+
saveResult: "success",
|
|
241
|
+
theme: "light",
|
|
242
|
+
},
|
|
243
|
+
render: (args, context) => (
|
|
244
|
+
<SandboxStory
|
|
245
|
+
key={JSON.stringify([args, context.globals.theme])}
|
|
246
|
+
{...args}
|
|
247
|
+
theme={context.globals.theme === "dark" ? "dark" : "light"}
|
|
248
|
+
/>
|
|
249
|
+
),
|
|
250
|
+
} satisfies Meta<typeof SandboxStory>;
|
|
251
|
+
export default meta;
|
|
252
|
+
type Story = StoryObj<typeof meta>;
|
|
253
|
+
|
|
254
|
+
export const ExistingNotebookPreparing: Story = {
|
|
255
|
+
name: "Startup notice / preparing",
|
|
256
|
+
};
|
|
257
|
+
export const EmptyNotebookPreparing: Story = {
|
|
258
|
+
name: "Empty notebook / preparing",
|
|
259
|
+
args: { existingCells: false },
|
|
260
|
+
};
|
|
261
|
+
export const StartingKernel: Story = {
|
|
262
|
+
name: "Startup notice / starting kernel",
|
|
263
|
+
args: { phase: "starting" },
|
|
264
|
+
};
|
|
265
|
+
export const ExistingNotebookFailed: Story = {
|
|
266
|
+
name: "Startup notice / failed",
|
|
267
|
+
args: { phase: "failed" },
|
|
268
|
+
};
|
|
269
|
+
export const EmptyNotebookFailed: Story = {
|
|
270
|
+
name: "Empty notebook / failed",
|
|
271
|
+
args: { phase: "failed", existingCells: false },
|
|
272
|
+
};
|
|
273
|
+
export const PackagesPreparing: Story = {
|
|
274
|
+
name: "Setup details / preparing",
|
|
275
|
+
args: { surface: "packages" },
|
|
276
|
+
};
|
|
277
|
+
export const PackagesFailed: Story = {
|
|
278
|
+
name: "Setup details / failed",
|
|
279
|
+
args: { surface: "packages", phase: "failed" },
|
|
280
|
+
};
|
|
281
|
+
export const PackagesReady: Story = {
|
|
282
|
+
name: "Status row / ready",
|
|
283
|
+
args: { surface: "packages", phase: "ready" },
|
|
284
|
+
};
|
|
285
|
+
export const PackagesSyncing: Story = {
|
|
286
|
+
name: "Status row / syncing",
|
|
287
|
+
args: { surface: "packages", phase: "syncing" },
|
|
288
|
+
};
|
|
289
|
+
export const PackagesSyncFailed: Story = {
|
|
290
|
+
name: "Setup details / sync failed",
|
|
291
|
+
args: { surface: "packages", phase: "sync-failed" },
|
|
292
|
+
};
|
|
293
|
+
export const PixiPackagesReady: Story = {
|
|
294
|
+
name: "Status row / pixi",
|
|
295
|
+
args: { surface: "packages", phase: "ready", backend: "pixi" },
|
|
296
|
+
};
|
|
297
|
+
export const ManifestEditor: Story = {
|
|
298
|
+
name: "Manifest / edit",
|
|
299
|
+
args: { surface: "manifest", phase: "failed" },
|
|
300
|
+
};
|
|
301
|
+
export const ManifestSyncFails: Story = {
|
|
302
|
+
name: "Manifest / failed save",
|
|
303
|
+
args: { surface: "manifest", phase: "failed", saveResult: "failure" },
|
|
304
|
+
};
|
|
305
|
+
export const ManifestChangedOnDisk: Story = {
|
|
306
|
+
name: "Manifest / changed on disk",
|
|
307
|
+
args: { surface: "manifest", phase: "failed", saveResult: "stale" },
|
|
308
|
+
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as e}from"./rolldown-runtime-B0Z9INg1.js";import{c as t}from"./useEvent-Dc9HkKI2.js";import{t as n}from"./react-CUdNIagt.js";import{Fn as r,Nn as i,_n as a,cn as o,hn as s,in as c,ln as l,nn as u,on as d,qn as f,rn as p,sn as m,vn as h}from"./cells-DcI93as7.js";import{t as g}from"./compiler-runtime-BQ9S8nyo.js";import{C as _,O as v,k as y}from"./utils-B3E7otfg.js";import{O as b,d as x,f as S,i as C,n as w,u as T}from"./ai-model-dropdown-CFjRFxPs.js";import{N as E}from"./config-D4PQ0ExB.js";import{t as D}from"./jsx-runtime-B74pBk57.js";import{o as O}from"./alert-dialog-CTZhLA-n.js";import{l as k}from"./select-C_hPB6Bz.js";import{t as A}from"./tooltip-Dnxk1tcQ.js";import{t as j}from"./button-BoklZTGL.js";import{s as M}from"./arrays-BqUx5USx.js";import{r as N}from"./requests-yTHMxhVa.js";import{t as P}from"./createLucideIcon-rHn2EdoM.js";import{r as F}from"./useNumberFormatter-C4-_TnkF.js";import{M as I,T as L,b as R,j as z,p as B,w as V}from"./write-secret-modal-B5x3omai.js";import{r as H}from"./input-DPJmbuuZ.js";import{t as U}from"./settings-DlKTeV_0.js";import{t as W}from"./use-toast-CC89xOwH.js";import{r as ee}from"./useDebounce-DMbg9X18.js";import{Rr as G,Ui as K}from"./index-D3ydSabW.js";import{n as q}from"./useInterval-ChchS0Rl.js";var J=P(`power-off`,[[`path`,{d:`M18.36 6.64A9 9 0 0 1 20.77 15`,key:`dxknvb`}],[`path`,{d:`M6.16 6.16a9 9 0 1 0 12.68 12.68`,key:`1x7qb5`}],[`path`,{d:`M12 2v4`,key:`3427ic`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}]]),Y=g(),X=D(),Z=e=>{let t=(0,Y.c)(15),{description:n,disabled:r,tooltip:i}=e,a=r!==void 0&&r,o=i===void 0?`Shutdown`:i,{openConfirm:s,closeModal:c}=R(),{sendShutdown:l}=N(),u;t[0]===l?u=t[1]:(u=()=>{l(),setTimeout(te,200)},t[0]=l,t[1]=u);let d=u;if(E())return null;let f=a?`disabled`:`red`,p;t[2]!==c||t[3]!==n||t[4]!==d||t[5]!==s?(p=e=>{e.stopPropagation(),s({title:`Shutdown`,description:n,variant:`destructive`,confirmAction:(0,X.jsx)(O,{onClick:()=>{d(),c()},"aria-label":`Confirm Shutdown`,children:`Shutdown`})})},t[2]=c,t[3]=n,t[4]=d,t[5]=s,t[6]=p):p=t[6];let m;t[7]===Symbol.for(`react.memo_cache_sentinel`)?(m=(0,X.jsx)(F,{strokeWidth:1}),t[7]=m):m=t[7];let h;t[8]!==a||t[9]!==f||t[10]!==p?(h=(0,X.jsx)(q,{"aria-label":`Shutdown`,"data-testid":`shutdown-button`,shape:`circle`,size:`small`,color:f,className:`h-[27px] w-[27px]`,disabled:a,onClick:p,children:m}),t[8]=a,t[9]=f,t[10]=p,t[11]=h):h=t[11];let g;return t[12]!==h||t[13]!==o?(g=(0,X.jsx)(A,{content:o,children:h}),t[12]=h,t[13]=o,t[14]=g):g=t[14],g};function te(){window.close()}var Q=e(n(),1),ne=100,re=()=>{let e=(0,Y.c)(37),[t,n]=_(),{saveAppConfig:a}=N(),s=(0,Q.useId)(),h=(0,Q.useId)(),g;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(g=i(v),e[0]=g):g=e[0];let y;e[1]===t?y=e[2]:(y={resolver:g,defaultValues:t},e[1]=t,e[2]=y);let b=r(y),C;e[3]!==a||e[4]!==n?(C=async e=>{await a({config:e}).then(()=>{n(e)}).catch(()=>{n(e)})},e[3]=a,e[4]=n,e[5]=C):C=e[5];let w=C,T;e[6]===w?T=e[7]:(T=e=>{w(e)},e[6]=w,e[7]=T);let E=ee(T,ne),D;e[8]===t.width?D=e[9]:(D=[t.width],e[8]=t.width,e[9]=D),(0,Q.useEffect)(ie,D);let O;e[10]!==E||e[11]!==b?(O=b.handleSubmit(E),e[10]=E,e[11]=b,e[12]=O):O=e[12];let k;e[13]===Symbol.for(`react.memo_cache_sentinel`)?(k=(0,X.jsxs)(`div`,{children:[(0,X.jsx)(S,{children:`Notebook Settings`}),(0,X.jsx)(x,{children:`Configure how your notebook or application looks and behaves.`})]}),e[13]=k):k=e[13];let A;e[14]===b.control?A=e[15]:(A=(0,X.jsxs)($,{title:`Display`,children:[(0,X.jsx)(d,{control:b.control,name:`width`,render:oe}),(0,X.jsx)(d,{control:b.control,name:`app_title`,render:se})]}),e[14]=b.control,e[15]=A);let j;e[16]===b.control?j=e[17]:(j=(0,X.jsxs)($,{title:`Custom Files`,children:[(0,X.jsx)(d,{control:b.control,name:`css_file`,render:ce}),(0,X.jsx)(d,{control:b.control,name:`html_head_file`,render:le})]}),e[16]=b.control,e[17]=j);let P;e[18]===b.control?P=e[19]:(P=(0,X.jsx)($,{title:`Data`,children:(0,X.jsx)(d,{control:b.control,name:`sql_output`,render:de})}),e[18]=b.control,e[19]=P);let F;e[20]!==s||e[21]!==h?(F=e=>{let{field:t}=e;return(0,X.jsxs)(`div`,{className:`flex flex-col gap-y-1`,children:[(0,X.jsxs)(m,{className:`flex flex-col gap-2`,children:[(0,X.jsx)(p,{children:(0,X.jsxs)(`div`,{className:`flex gap-4`,children:[(0,X.jsxs)(`div`,{className:`flex items-center space-x-2`,children:[(0,X.jsx)(f,{id:s,"data-testid":`html-checkbox`,checked:t.value.includes(`html`),onCheckedChange:()=>{t.onChange(M(t.value,`html`))}}),(0,X.jsx)(o,{htmlFor:s,children:`HTML`})]}),(0,X.jsxs)(`div`,{className:`flex items-center space-x-2`,children:[(0,X.jsx)(f,{id:h,"data-testid":`ipynb-checkbox`,checked:t.value.includes(`ipynb`),onCheckedChange:()=>{t.onChange(M(t.value,`ipynb`))}}),(0,X.jsx)(o,{htmlFor:h,children:`IPYNB`})]})]})}),(0,X.jsx)(l,{})]}),(0,X.jsxs)(c,{children:[`When enabled, marimo will periodically save this notebook in your selected formats (HTML, IPYNB) to a folder named`,` `,(0,X.jsx)(G,{className:`inline`,children:`__marimo__`}),` next to your notebook file.`]})]})},e[20]=s,e[21]=h,e[22]=F):F=e[22];let I;e[23]!==b.control||e[24]!==F?(I=(0,X.jsx)($,{title:`Exporting outputs`,children:(0,X.jsx)(d,{control:b.control,name:`auto_download`,render:F})}),e[23]=b.control,e[24]=F,e[25]=I):I=e[25];let L;e[26]!==I||e[27]!==A||e[28]!==j||e[29]!==P?(L=(0,X.jsxs)(`div`,{className:`grid grid-cols-2 gap-x-8 gap-y-4`,children:[A,j,P,I]}),e[26]=I,e[27]=A,e[28]=j,e[29]=P,e[30]=L):L=e[30];let R;e[31]!==L||e[32]!==O?(R=(0,X.jsxs)(`form`,{onChange:O,className:`flex flex-col gap-6`,children:[k,L]}),e[31]=L,e[32]=O,e[33]=R):R=e[33];let z;return e[34]!==b||e[35]!==R?(z=(0,X.jsx)(u,{...b,children:R}),e[34]=b,e[35]=R,e[36]=z):z=e[36],z},$=e=>{let t=(0,Y.c)(5),{title:n,children:r}=e,i;t[0]===n?i=t[1]:(i=(0,X.jsx)(`h3`,{className:`text-base font-semibold mb-1`,children:n}),t[0]=n,t[1]=i);let a;return t[2]!==r||t[3]!==i?(a=(0,X.jsxs)(`div`,{className:`flex flex-col gap-y-2`,children:[i,r]}),t[2]=r,t[3]=i,t[4]=a):a=t[4],a};function ie(){window.dispatchEvent(new Event(`resize`))}function ae(e){return(0,X.jsx)(`option`,{value:e,children:e},e)}function oe(e){let{field:t}=e;return(0,X.jsxs)(m,{className:`flex flex-row items-center space-x-1 space-y-0`,children:[(0,X.jsx)(o,{children:`Width`}),(0,X.jsx)(p,{children:(0,X.jsx)(k,{"data-testid":`app-width-select`,onChange:e=>t.onChange(e.target.value),value:t.value,disabled:t.disabled,className:`inline-flex mr-2`,children:b().map(ae)})}),(0,X.jsx)(l,{})]})}function se(e){let{field:t}=e;return(0,X.jsxs)(`div`,{className:`flex flex-col gap-y-1`,children:[(0,X.jsxs)(m,{className:`flex flex-row items-center space-x-1 space-y-0`,children:[(0,X.jsx)(o,{children:`App title`}),(0,X.jsx)(p,{children:(0,X.jsx)(H,{...t,value:t.value??``,onChange:e=>{t.onChange(e.target.value),y.safeParse(e.target.value).success&&(document.title=e.target.value)}})}),(0,X.jsx)(l,{})]}),(0,X.jsx)(c,{children:`The application title is put in the title tag in the HTML code and typically displayed in the title bar of the browser window.`})]})}function ce(e){let{field:t}=e;return(0,X.jsxs)(`div`,{className:`flex flex-col gap-y-1`,children:[(0,X.jsxs)(m,{className:`flex flex-row items-center space-x-1 space-y-0`,children:[(0,X.jsx)(o,{className:`shrink-0`,children:`Custom CSS`}),(0,X.jsx)(p,{children:(0,X.jsx)(H,{...t,value:t.value??``,placeholder:`custom.css`,onChange:e=>{t.onChange(e.target.value),y.safeParse(e.target.value).success&&(document.title=e.target.value)}})}),(0,X.jsx)(l,{})]}),(0,X.jsx)(c,{children:`A filepath to a custom css file to be injected into the notebook.`})]})}function le(e){let{field:t}=e;return(0,X.jsxs)(`div`,{className:`flex flex-col gap-y-1`,children:[(0,X.jsxs)(m,{className:`flex flex-row items-center space-x-1 space-y-0`,children:[(0,X.jsx)(o,{className:`shrink-0`,children:`HTML Head`}),(0,X.jsx)(p,{children:(0,X.jsx)(H,{...t,value:t.value??``,placeholder:`head.html`,onChange:e=>{t.onChange(e.target.value)}})}),(0,X.jsx)(l,{})]}),(0,X.jsxs)(c,{children:[`A filepath to an HTML file to be injected into the`,` `,(0,X.jsx)(G,{className:`inline`,children:`<head/>`}),` section of the notebook. Use this to add analytics, custom fonts, meta tags, or external scripts.`]})]})}function ue(e){return(0,X.jsx)(`option`,{value:e.value,children:e.label},e.value)}function de(e){let{field:t}=e;return(0,X.jsxs)(`div`,{className:`flex flex-col gap-y-1`,children:[(0,X.jsxs)(m,{className:`flex flex-row items-center space-x-1 space-y-0`,children:[(0,X.jsx)(o,{children:`SQL Output Type`}),(0,X.jsx)(p,{children:(0,X.jsx)(k,{"data-testid":`sql-output-select`,onChange:e=>{t.onChange(e.target.value),W({title:`Kernel Restart Required`,description:`This change requires a kernel restart to take effect.`})},value:t.value,disabled:t.disabled,className:`inline-flex mr-2`,children:T.map(ue)})}),(0,X.jsx)(l,{})]}),(0,X.jsxs)(c,{children:[`The Python type returned by a SQL cell. For best performance with large datasets, we recommend using`,` `,(0,X.jsx)(G,{className:`inline`,children:`native`}),`. See the`,` `,(0,X.jsx)(B,{href:`https://docs.marimo.io/guides/working_with_data/sql`,children:`SQL guide`}),` `,`for more information.`]})]})}var fe=e=>{let n=(0,Y.c)(32),{showAppConfig:r,disabled:i,tooltip:o}=e,c=r===void 0||r,l=i!==void 0&&i,u=o===void 0?`Settings`:o,[d,f]=t(w),p=l?`disabled`:`hint-green`,m;n[0]===Symbol.for(`react.memo_cache_sentinel`)?(m=(0,X.jsx)(U,{strokeWidth:1.8}),n[0]=m):m=n[0];let g;n[1]===u?g=n[2]:(g=(0,X.jsx)(A,{content:u,children:m}),n[1]=u,n[2]=g);let _;n[3]!==l||n[4]!==p||n[5]!==g?(_=(0,X.jsx)(q,{"aria-label":`Config`,"data-testid":`app-config-button`,shape:`circle`,size:`small`,className:`h-[27px] w-[27px]`,disabled:l,color:p,children:g}),n[3]=l,n[4]=p,n[5]=g,n[6]=_):_=n[6];let v=_,y;n[7]===Symbol.for(`react.memo_cache_sentinel`)?(y=(0,X.jsxs)(L,{className:`w-[90vw] h-[90vh] overflow-hidden sm:max-w-5xl top-[5vh] p-0`,children:[(0,X.jsx)(K,{children:(0,X.jsx)(z,{children:`User settings`})}),(0,X.jsx)(C,{})]}),n[7]=y):y=n[7];let b=y;if(!c){let e;n[8]===v?e=n[9]:(e=(0,X.jsx)(I,{children:v}),n[8]=v,n[9]=e);let t;return n[10]!==f||n[11]!==d||n[12]!==e?(t=(0,X.jsxs)(V,{open:d,onOpenChange:f,children:[e,b]}),n[10]=f,n[11]=d,n[12]=e,n[13]=t):t=n[13],t}let x;n[14]===v?x=n[15]:(x=(0,X.jsx)(h,{asChild:!0,children:v}),n[14]=v,n[15]=x);let S,T;n[16]===Symbol.for(`react.memo_cache_sentinel`)?(S=(0,X.jsx)(re,{}),T=(0,X.jsx)(`div`,{className:`h-px bg-border my-2`}),n[16]=S,n[17]=T):(S=n[16],T=n[17]);let E;n[18]===f?E=n[19]:(E=()=>f(!0),n[18]=f,n[19]=E);let D;n[20]===Symbol.for(`react.memo_cache_sentinel`)?(D=(0,X.jsx)(U,{strokeWidth:1.8,className:`w-4 h-4 mr-2`}),n[20]=D):D=n[20];let O;n[21]===E?O=n[22]:(O=(0,X.jsxs)(a,{className:`w-[650px] overflow-auto max-h-[80vh] max-w-[80vw]`,align:`end`,side:`bottom`,onFocusOutside:pe,children:[S,T,(0,X.jsxs)(j,{onClick:E,variant:`link`,className:`px-0`,children:[D,`User settings`]})]}),n[21]=E,n[22]=O);let k;n[23]!==O||n[24]!==x?(k=(0,X.jsxs)(s,{children:[x,O]}),n[23]=O,n[24]=x,n[25]=k):k=n[25];let M;n[26]!==f||n[27]!==d?(M=(0,X.jsx)(V,{open:d,onOpenChange:f,children:b}),n[26]=f,n[27]=d,n[28]=M):M=n[28];let N;return n[29]!==k||n[30]!==M?(N=(0,X.jsxs)(X.Fragment,{children:[k,M]}),n[29]=k,n[30]=M,n[31]=N):N=n[31],N};function pe(e){return e.preventDefault()}export{Z as n,J as r,fe as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as e}from"./rolldown-runtime-B0Z9INg1.js";import{l as t}from"./useEvent-Dc9HkKI2.js";import{t as n}from"./react-CUdNIagt.js";import{t as r}from"./compiler-runtime-BQ9S8nyo.js";import{t as i}from"./cn-ldLVeaqm.js";import{t as a}from"./jsx-runtime-B74pBk57.js";import{a as o,c as s,i as c,l,n as u,o as d,r as f,s as p,t as m,u as h}from"./alert-dialog-CTZhLA-n.js";import{t as g}from"./button-BoklZTGL.js";import{r as _}from"./requests-yTHMxhVa.js";import{Z as v}from"./panels-DvYa8VJO.js";import{I as y,L as b}from"./RunButton-Bo4tYCqW.js";import{t as x}from"./database-zap-CrkOvbyN.js";import{t as S}from"./trash-2-BJG-7Qob.js";import{t as C}from"./use-toast-CC89xOwH.js";import{t as w}from"./context-BFOBKCJB.js";import{i as T}from"./numbers-DsgsDslU.js";import{n as E}from"./useAsyncData-DucTwMkf.js";import{$r as D,pa as O}from"./index-D3ydSabW.js";import{t as k}from"./empty-state-CzxjZqGW.js";var A=r(),j=e(n(),1),M=a(),N=e=>{let t=(0,A.c)(27),{children:n,title:r,description:i,onConfirm:a,confirmText:g,cancelText:_,destructive:v}=e,y=g===void 0?`Continue`:g,b=_===void 0?`Cancel`:_,x=v!==void 0&&v,[S,C]=j.useState(!1),w;t[0]===a?w=t[1]:(w=()=>{a(),C(!1)},t[0]=a,t[1]=w);let T=w,E=x?d:u,D;t[2]===n?D=t[3]:(D=(0,M.jsx)(h,{asChild:!0,children:n}),t[2]=n,t[3]=D);let O;t[4]===r?O=t[5]:(O=(0,M.jsx)(l,{children:r}),t[4]=r,t[5]=O);let k;t[6]===i?k=t[7]:(k=(0,M.jsx)(o,{children:i}),t[6]=i,t[7]=k);let N;t[8]!==O||t[9]!==k?(N=(0,M.jsxs)(s,{children:[O,k]}),t[8]=O,t[9]=k,t[10]=N):N=t[10];let P;t[11]===b?P=t[12]:(P=(0,M.jsx)(f,{children:b}),t[11]=b,t[12]=P);let F;t[13]!==E||t[14]!==y||t[15]!==T?(F=(0,M.jsx)(E,{onClick:T,children:y}),t[13]=E,t[14]=y,t[15]=T,t[16]=F):F=t[16];let I;t[17]!==F||t[18]!==P?(I=(0,M.jsxs)(p,{children:[P,F]}),t[17]=F,t[18]=P,t[19]=I):I=t[19];let L;t[20]!==I||t[21]!==N?(L=(0,M.jsxs)(c,{children:[N,I]}),t[20]=I,t[21]=N,t[22]=L):L=t[22];let R;return t[23]!==S||t[24]!==L||t[25]!==D?(R=(0,M.jsxs)(m,{open:S,onOpenChange:C,children:[D,L]}),t[23]=S,t[24]=L,t[25]=D,t[26]=R):R=t[26],R},P=()=>{let{clearCache:e,getCacheInfo:n}=_(),r=t(v),[a,o]=(0,j.useState)(!1),{locale:s}=w(),{isPending:c,isFetching:l,refetch:u}=E(async()=>{await n(),await new Promise(e=>setTimeout(e,500))},[]),d=async()=>{try{o(!0),await e(),C({title:`Cache purged`,description:`All cached data has been cleared`}),u()}catch(e){C({title:`Error`,description:e instanceof Error?e.message:`Failed to purge cache`,variant:`danger`})}finally{o(!1)}};if(c&&!r)return(0,M.jsx)(D,{size:`medium`,centered:!0});let f=(0,M.jsxs)(g,{variant:`outline`,size:`sm`,onClick:u,disabled:l,children:[l?(0,M.jsx)(D,{size:`small`,className:`w-4 h-4 mr-2`}):(0,M.jsx)(O,{className:`w-4 h-4 mr-2`}),`Refresh`]});if(!r)return(0,M.jsx)(k,{title:`No cache data`,description:`Cache information is not available.`,icon:(0,M.jsx)(x,{}),action:f});let p=r.hits,m=r.misses,h=r.time,A=r.disk_total,P=r.disk_to_free,I=p+m,L=I>0?p/I*100:0;return I===0?(0,M.jsx)(k,{title:`No cache activity`,description:`The cache has not been used yet. Cached functions will appear here once they are executed.`,icon:(0,M.jsx)(x,{}),action:f}):(0,M.jsx)(`div`,{className:`flex flex-col h-full overflow-auto`,children:(0,M.jsxs)(`div`,{className:`flex flex-col gap-4 p-4 h-full`,children:[(0,M.jsx)(`div`,{className:`flex items-center justify-end`,children:(0,M.jsx)(g,{variant:`ghost`,size:`icon`,className:`h-6 w-6`,onClick:u,disabled:l,children:(0,M.jsx)(O,{className:i(`h-4 w-4 text-muted-foreground hover:text-foreground`,l&&`animate-[spin_0.5s]`)})})}),(0,M.jsxs)(`div`,{className:`space-y-3`,children:[(0,M.jsx)(`h3`,{className:`text-sm font-semibold text-foreground`,children:`Statistics`}),(0,M.jsxs)(`div`,{className:`grid grid-cols-2 gap-3`,children:[(0,M.jsx)(F,{label:`Time saved`,value:b(h,s),description:`Total execution time saved`}),(0,M.jsx)(F,{label:`Hit rate`,value:I>0?`${T(L,s)}%`:`—`,description:`${T(p,s)} hits / ${T(I,s)} total`}),(0,M.jsx)(F,{label:`Cache hits`,value:T(p,s),description:`Successful cache retrievals`}),(0,M.jsx)(F,{label:`Cache misses`,value:T(m,s),description:`Cache not found`})]})]}),A>0&&(0,M.jsxs)(`div`,{className:`space-y-3 pt-2 border-t`,children:[(0,M.jsx)(`h3`,{className:`text-sm font-semibold text-foreground`,children:`Storage`}),(0,M.jsx)(`div`,{className:`grid grid-cols-1 gap-3`,children:(0,M.jsx)(F,{label:`Disk usage`,value:y(A,s),description:P>0?`${y(P,s)} can be freed`:`Cache storage on disk`})})]}),(0,M.jsx)(`div`,{className:`my-auto`}),(0,M.jsx)(`div`,{className:`pt-2 border-t`,children:(0,M.jsx)(N,{title:`Purge cache?`,description:`This will permanently delete all cached data. This action cannot be undone.`,confirmText:`Purge`,destructive:!0,onConfirm:d,children:(0,M.jsxs)(g,{variant:`outlineDestructive`,size:`xs`,disabled:a,className:`w-full`,children:[a?(0,M.jsx)(D,{size:`small`,className:`w-3 h-3 mr-2`}):(0,M.jsx)(S,{className:`w-3 h-3 mr-2`}),`Purge Cache`]})})})]})})},F=e=>{let t=(0,A.c)(10),{label:n,value:r,description:i}=e,a;t[0]===n?a=t[1]:(a=(0,M.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:n}),t[0]=n,t[1]=a);let o;t[2]===r?o=t[3]:(o=(0,M.jsx)(`span`,{className:`text-lg font-semibold`,children:r}),t[2]=r,t[3]=o);let s;t[4]===i?s=t[5]:(s=i&&(0,M.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:i}),t[4]=i,t[5]=s);let c;return t[6]!==a||t[7]!==o||t[8]!==s?(c=(0,M.jsxs)(`div`,{className:`flex flex-col gap-1 p-3 rounded-lg border bg-card`,children:[a,o,s]}),t[6]=a,t[7]=o,t[8]=s,t[9]=c):c=t[9],c};export{P as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as e,c as t,f as n,l as r,r as i,t as ee}from"./useEvent-Dc9HkKI2.js";import{t as a}from"./compiler-runtime-BQ9S8nyo.js";import{t as o}from"./utils-B3E7otfg.js";import{g as s}from"./useEventListener-BdZUApHd.js";import{t as c}from"./invariant-Ci2dTZ72.js";import{r as l}from"./constants-BDbGiS7O.js";import{t as u}from"./Deferred-CrTnjj37.js";import{t as d}from"./session-C8nQMsOE.js";var f=a();function p(e,t){if(e==null)throw Error(t||`Expected value but got ${e}`)}function m(){return typeof document<`u`&&document.querySelector(`marimo-wasm`)!==null}function h(){let e=i.get(y);return p(e,`internal-error: initial mode not found`),c(e!==`present`,`internal-error: initial mode cannot be 'present'`),e}function g(e){return e===`read`||e===`home`||e===`gallery`?e:e===`edit`?`present`:`edit`}async function _(e){let t=i.get(v);if(t.mode!==`edit`){await e();return}i.set(v,{...t,mode:`present`});try{await new Promise(e=>setTimeout(e,100)),await new Promise(e=>requestAnimationFrame(e)),await new Promise(e=>requestAnimationFrame(e)),await e()}finally{i.set(v,t)}}var v=n({mode:o()?`read`:`not-set`,cellAnchor:null}),y=n(void 0);function b(){let e=i.get(y);return e!==`home`&&e!==`gallery`}var x=n(!1);function S(){let e=(0,f.c)(1),{mode:t}=r(v),n=r(x),i;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(i=new URLSearchParams(window.location.search).get(l.kiosk),e[0]=i):i=e[0],t!==`read`&&!n&&i!==`true`}var C={NOT_STARTED:`NOT_STARTED`,CONNECTING:`CONNECTING`,OPEN:`OPEN`,CLOSING:`CLOSING`,CLOSED:`CLOSED`},w={KERNEL_DISCONNECTED:`KERNEL_DISCONNECTED`,KERNEL_STARTUP_ERROR:`KERNEL_STARTUP_ERROR`},T=n({state:C.NOT_STARTED});function E(){return e(T,e=>e.state===C.OPEN)}function D(){return b()?E():Promise.resolve()}var O=n(e=>e(T).state===C.CONNECTING);n(e=>e(T).state===C.OPEN);var k=n(e=>{let t=e(T);return t.state===C.OPEN||t.state===C.NOT_STARTED}),A=n(e=>e(T).state===C.CLOSED),j=n(e=>e(T).state===C.NOT_STARTED);function M(e){return e===C.CLOSED}function N(e){return e===C.CONNECTING}function P(e){return e===C.OPEN}function F(e){return e===C.CLOSING}function I(e){return e===C.NOT_STARTED}function L(e){return e===C.CLOSED||e===C.CLOSING||e===C.CONNECTING}function R(e){switch(e){case C.CLOSED:return`App disconnected`;case C.CONNECTING:return`Connecting to a runtime ...`;case C.CLOSING:return`App disconnecting...`;case C.OPEN:return``;case C.NOT_STARTED:return`Click to connect to a runtime`;default:return``}}function z(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;for(let t of Object.values(e))if(typeof t!=`string`)return!1;return!0}function B(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;return!(!z(t.files)||t.modelNotifications!==void 0&&!Array.isArray(t.modelNotifications))}function V(){let e=typeof window>`u`?void 0:window.__MARIMO_STATIC__;return B(e)?e:void 0}function H(){return V()!==void 0}function U(){let e=V();return c(e!==void 0,`Not a static notebook`),e.files}function W(){return V()?.modelNotifications}var G=class{initialHealthyCheck=new u;config;lazy;constructor(e,t=!1){this.config=e,this.lazy=t;try{new URL(this.config.url)}catch(e){throw Error(`Invalid runtime URL: ${this.config.url}. ${e instanceof Error?e.message:`Unknown error`}`,{cause:e})}this.lazy||this.init()}get isLazy(){return this.lazy}get httpURL(){return new URL(this.config.url)}get isSameOrigin(){return this.httpURL.origin===window.location.origin}get isServerless(){return m()||o()||H()}formatHttpURL({path:e=``,searchParams:t,restrictToKnownQueryParams:n=!0}){let r=this.httpURL,i=new URLSearchParams(window.location.search);if(t)for(let[e,n]of t.entries())r.searchParams.set(e,n);for(let[e,t]of i.entries())n&&!Object.values(l).includes(e)||r.searchParams.set(e,t);return r.pathname=`${r.pathname.replace(/\/$/,``)}/${e.replace(/^\//,``)}`,r.hash=``,r}appendCrossOriginAuth(e){return!this.isSameOrigin&&this.config.authToken&&e.searchParams.set(l.accessToken,this.config.authToken),e}formatNavigableHttpURL(e,t){let n=this.formatHttpURL({path:e,searchParams:t});return n.searchParams.delete(l.accessToken),this.appendCrossOriginAuth(n)}formatWsURL(e,t){let n=this.formatHttpURL({path:e,searchParams:t,restrictToKnownQueryParams:!1});return K(this.appendCrossOriginAuth(n).toString())}getSessionSearchParams(e){let t=new URL(this.config.url),n=new URLSearchParams(t.search);return new URLSearchParams(window.location.search).forEach((e,t)=>{n.has(t)||n.set(t,e)}),n.set(l.sessionId,e),n}getWsURL(e){return this.formatWsURL(`/ws`,this.getSessionSearchParams(e))}getSseURL(e){let t=this.formatHttpURL({path:`/sse`,searchParams:this.getSessionSearchParams(e),restrictToKnownQueryParams:!1});return t.searchParams.delete(l.accessToken),t}getWsSyncURL(e){return this.formatWsURL(`/ws_sync`,this.getSessionSearchParams(e))}getTerminalWsURL(e){let t=this.formatWsURL(`/terminal/ws`);return e&&(t.searchParams.set(`rows`,String(e.rows)),t.searchParams.set(`cols`,String(e.cols))),t}getLSPURL(e){if(e===`copilot`){let t=this.formatWsURL(`/lsp/${e}`),n=t.searchParams.get(l.accessToken);return t.search=``,n&&t.searchParams.set(l.accessToken,n),t}return this.formatWsURL(`/lsp/${e}`)}getAiURL(e){return this.formatHttpURL({path:`/api/ai/${e}`})}healthURL(){return this.formatHttpURL({path:`/health`})}async fetchHealth(){try{return await fetch(this.healthURL().toString())}catch(e){return s.error(`Failed to check health: ${e instanceof Error?e.message:`Unknown error`}`,{cause:e}),null}}async reconcileFromHealth(){if(this.isServerless)return!0;let e=await this.fetchHealth();if(!e)return!1;if(e.redirected){s.debug(`Runtime redirected to ${e.url}`);let t=new URL(e.url);t.pathname=t.pathname.replace(/\/health$/,``),this.config.url=t.toString()}return e.ok&&this.setDOMBaseUri(this.config.url),e.ok}async probeHealth(){return this.isServerless?!0:(await this.fetchHealth())?.ok??!1}setDOMBaseUri(e){e=e.split(`?`,1)[0],e.endsWith(`/`)||(e+=`/`);let t=document.querySelector(`base`);t?t.setAttribute(`href`,e):(t=document.createElement(`base`),t.setAttribute(`href`,e),document.head.append(t))}async init(e){s.debug(`Initializing runtime...`);let t=0;for(;!await this.reconcileFromHealth();){if(t>=25){s.error(`Failed to connect after 25 retries`),this.initialHealthyCheck.reject(Error(`Failed to connect after 25 retries`));return}if(!e?.disableRetryDelay){let e=Math.min(100*1.2**t,2e3);await new Promise(t=>setTimeout(t,e))}t++}s.debug(`Runtime is healthy`),this.initialHealthyCheck.resolve()}async waitForHealthy(){return this.initialHealthyCheck.promise}headers(){let e={"Marimo-Session-Id":d(),"Marimo-Server-Token":this.config.serverToken??``,"x-runtime-url":this.httpURL.toString()};return this.config.authToken&&(e.Authorization=`Bearer ${this.config.authToken}`),e}sessionHeaders(){return{"Marimo-Session-Id":d()}}};function K(e){if(!e.startsWith(`http`)){s.warn(`URL must start with http: ${e}`);let t=new URL(e);return t.protocol=`ws`,t}return new URL(e.replace(/^http/,`ws`))}function q(){let e=new URL(document.baseURI);return e.search=``,e.hash=``,e.toString()}var J={lazy:!0,url:q()},Y=n(J),X=n(e=>{let t=e(Y);return new G(t,t.lazy)});function Z(){return r(X)}function Q(){let e=(0,f.c)(4),n=Z(),[r,i]=t(T),a;return e[0]!==r.state||e[1]!==n||e[2]!==i?(a=async()=>{I(r.state)?(i({state:C.CONNECTING}),await n.init()):s.log(`Runtime already started or starting...`)},e[0]=r.state,e[1]=n,e[2]=i,e[3]=a):a=e[3],ee(a)}function $(){return i.get(X)}function te(e){if(e.startsWith(`http`))return new URL(e);let t=$().httpURL.toString();return t.startsWith(`blob:`)&&(t=t.replace(`blob:`,``)),new URL(e,t)}export{g as A,D as C,y as D,h as E,v as M,m as N,x as O,p as P,E as S,C as T,k as _,Q as a,O as b,U as c,M as d,F as f,I as g,L as h,Y as i,S as j,_ as k,H as l,N as m,te as n,Z as o,P as p,$ as r,W as s,J as t,R as u,T as v,w,j as x,A as y};
|