@marimo-team/frontend 0.19.8-dev21 → 0.19.8-dev24
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-B098edeX.js → ConnectedDataExplorerComponent-C1BlkUlk.js} +1 -1
- package/dist/assets/{JsonOutput-DsO4felE.js → JsonOutput-BPSYj_Kn.js} +3 -3
- package/dist/assets/{LazyAnyLanguageCodeMirror-CQP8KZWO.js → LazyAnyLanguageCodeMirror-BqosdyZU.js} +2 -2
- package/dist/assets/{MarimoErrorOutput-DrTj9k_Z.js → MarimoErrorOutput-DVEiP1Ym.js} +1 -1
- package/dist/assets/{RenderHTML-D9vJ9neG.js → RenderHTML-Bj4DW3wy.js} +1 -1
- package/dist/assets/{add-cell-with-ai-CPu9tI-Q.js → add-cell-with-ai-dpMkH_5a.js} +5 -5
- package/dist/assets/{add-database-form-CvczP0Mq.js → add-database-form-Bn_w5TEI.js} +1 -1
- package/dist/assets/{agent-panel-Dbh-hMbm.js → agent-panel-BSykBSj4.js} +1 -1
- package/dist/assets/{ai-model-dropdown-CODXtvnr.js → ai-model-dropdown-D8AFYZjU.js} +1 -1
- package/dist/assets/{any-language-editor-B1WBkbF4.js → any-language-editor-DyXJSyeK.js} +1 -1
- package/dist/assets/{app-config-button-BGuwQV5R.js → app-config-button-Ds61zRnG.js} +1 -1
- package/dist/assets/{architectureDiagram-VXUJARFQ-BsTgqTsh.js → architectureDiagram-VXUJARFQ-B8zMpJcM.js} +1 -1
- package/dist/assets/blob-Bgnx1kuY.js +1 -0
- package/dist/assets/{blockDiagram-VD42YOAC-CeZonq9z.js → blockDiagram-VD42YOAC-CF1a-_t0.js} +1 -1
- package/dist/assets/{c4Diagram-YG6GDRKO-CDPGRzUd.js → c4Diagram-YG6GDRKO-YIsEsUdQ.js} +1 -1
- package/dist/assets/{cache-panel-gTIhwBeU.js → cache-panel-C_9WDApV.js} +1 -1
- package/dist/assets/{cell-editor-BpkNlmop.js → cell-editor-90blTXig.js} +1 -1
- package/dist/assets/channel-CXFsg7SH.js +1 -0
- package/dist/assets/{chat-display-BnUDaREA.js → chat-display-letMHFni.js} +1 -1
- package/dist/assets/{chat-panel-BpDjUlzW.js → chat-panel-0qUKLNYu.js} +1 -1
- package/dist/assets/{chunk-5FQGJX7Z-CwvgJCug.js → chunk-5FQGJX7Z-T2jyw7ZD.js} +2 -2
- package/dist/assets/{chunk-ABZYJK2D-CtRGq-db.js → chunk-ABZYJK2D-D1A06qKo.js} +3 -3
- package/dist/assets/{chunk-ATLVNIR6-CXEe2jMF.js → chunk-ATLVNIR6-C5FWd1qN.js} +1 -1
- package/dist/assets/{chunk-B4BG7PRW-BVqt-NSK.js → chunk-B4BG7PRW-BEayfxv_.js} +1 -1
- package/dist/assets/{chunk-DI55MBZ5-C_mlVJmb.js → chunk-DI55MBZ5-BSrtupT8.js} +1 -1
- package/dist/assets/{chunk-EXTU4WIE-CN3BqsR0.js → chunk-EXTU4WIE-wi_fHsHN.js} +1 -1
- package/dist/assets/{chunk-JA3XYJ7Z-B5-JYmoA.js → chunk-JA3XYJ7Z-tKDxhnhw.js} +1 -1
- package/dist/assets/{chunk-JZLCHNYA-UFlatyc1.js → chunk-JZLCHNYA-DtvI9B9X.js} +1 -1
- package/dist/assets/{chunk-N4CR4FBY-BFF_Z7sG.js → chunk-N4CR4FBY-BQcJpHO7.js} +2 -2
- package/dist/assets/{chunk-QN33PNHL-DOgXIePg.js → chunk-QN33PNHL-BboKw3W6.js} +1 -1
- package/dist/assets/{chunk-QXUST7PY-CbBaWlhv.js → chunk-QXUST7PY-C4Ihfbmy.js} +1 -1
- package/dist/assets/{chunk-S3R3BYOJ-CM-pQ0EF.js → chunk-S3R3BYOJ-D1UiABQX.js} +1 -1
- package/dist/assets/{chunk-TZMSLE5B-Bs5ERkTF.js → chunk-TZMSLE5B-BjrxQwUX.js} +1 -1
- package/dist/assets/classDiagram-2ON5EDUG-BHD5dOKT.js +1 -0
- package/dist/assets/classDiagram-v2-WZHVMYZB-VYd80hrd.js +1 -0
- package/dist/assets/{code-block-37QAKDTI-CT7W9knZ.js → code-block-37QAKDTI-FUPT3-7o.js} +1 -1
- package/dist/assets/{column-preview-Bz3KIcIX.js → column-preview-BEosUUWh.js} +1 -1
- package/dist/assets/{command-PbcrObnK.js → command-BpjkI15h.js} +1 -1
- package/dist/assets/{command-palette-D8q355Sm.js → command-palette-BymLo8Sb.js} +1 -1
- package/dist/assets/{common-DRWuidzm.js → common-RVtJOXao.js} +1 -1
- package/dist/assets/{copy-icon-B9w72gBC.js → copy-icon-C9v8EtBA.js} +1 -1
- package/dist/assets/{dagre-6UL2VRFP-UK8bracd.js → dagre-6UL2VRFP-CX3NGWnu.js} +1 -1
- package/dist/assets/{data-grid-overlay-editor-2vr_zUfM.js → data-grid-overlay-editor-BTyw6887.js} +1 -1
- package/dist/assets/{datasource-Dkywo3Kg.js → datasource-Bl1__6xJ.js} +1 -1
- package/dist/assets/{dependency-graph-panel-ZnsWxFY3.js → dependency-graph-panel-C33q1RVn.js} +1 -1
- package/dist/assets/{diagram-PSM6KHXK-7QiPU-26.js → diagram-PSM6KHXK-C0Sfgs1J.js} +1 -1
- package/dist/assets/{diagram-QEK2KX5R-BbZsWUC4.js → diagram-QEK2KX5R-DYSkW6Ju.js} +1 -1
- package/dist/assets/{diagram-S2PKOQOG-SZ-twU4B.js → diagram-S2PKOQOG-CfHqQVo3.js} +1 -1
- package/dist/assets/{dist-DY1C8dgM.js → dist-h1RhtzUB.js} +1 -1
- package/dist/assets/{documentation-panel-CZJavCAM.js → documentation-panel-BWViNAJ6.js} +1 -1
- package/dist/assets/{download-CmdFQXRz.js → download-s-BdZdTz.js} +1 -1
- package/dist/assets/{edit-page-e6xxDbUd.js → edit-page-nMTiqKOs.js} +3 -3
- package/dist/assets/{erDiagram-Q2GNP2WA-BSmVh3Kt.js → erDiagram-Q2GNP2WA-BfRyUS6D.js} +1 -1
- package/dist/assets/{error-panel-BMcWP1VH.js → error-panel-BhPek3dt.js} +1 -1
- package/dist/assets/{es-CerBf9Z6.js → es-GXAIFcot.js} +1 -1
- package/dist/assets/{esm-C-53tlK5.js → esm-BK6tLEHQ.js} +1 -1
- package/dist/assets/{file-explorer-panel-th-ny103.js → file-explorer-panel-BGF99P_O.js} +1 -1
- package/dist/assets/{flowDiagram-NV44I4VS-2nYUYKvI.js → flowDiagram-NV44I4VS-DKkZCUwG.js} +1 -1
- package/dist/assets/{form-94alAnRh.js → form-CNEyFLKK.js} +1 -1
- package/dist/assets/{formats-CobRswjh.js → formats-DGZwRUPy.js} +1 -1
- package/dist/assets/gallery-page-1AmSypJ6.js +1 -0
- package/dist/assets/{ganttDiagram-JELNMOA3-B77PnMPw.js → ganttDiagram-JELNMOA3-J8yLTqxn.js} +1 -1
- package/dist/assets/{gitGraphDiagram-NY62KEGX-B-3aRelz.js → gitGraphDiagram-NY62KEGX-DXw3a-uS.js} +1 -1
- package/dist/assets/{glide-data-editor-B5UMCoFz.js → glide-data-editor-Cw8eE9Xn.js} +4 -4
- package/dist/assets/{home-page-Bgzw3IP3.js → home-page-Cs46vLcH.js} +1 -1
- package/dist/assets/{hooks-B_N-kbrq.js → hooks-C13qkLoi.js} +1 -1
- package/dist/assets/index-3CaNzO41.css +2 -0
- package/dist/assets/{index-U7La6ZBB.js → index-CxrD-UyN.js} +22 -22
- package/dist/assets/{infoDiagram-WHAUD3N6-_vys04Gc.js → infoDiagram-WHAUD3N6-32du45zK.js} +1 -1
- package/dist/assets/{journeyDiagram-XKPGCS4Q-CkD6eopP.js → journeyDiagram-XKPGCS4Q-Bmx7dA25.js} +1 -1
- package/dist/assets/{kanban-definition-3W4ZIXB7-kX5aL9Ug.js → kanban-definition-3W4ZIXB7-DJzhLwsl.js} +1 -1
- package/dist/assets/katex-axIMlGRc.js +1 -0
- package/dist/assets/{label-C9wP7Kp2.js → label-C--1sWU6.js} +1 -1
- package/dist/assets/{layout-D7NLGhPa.js → layout-ZtHfLqYp.js} +3 -3
- package/dist/assets/{linear-BxhToEEF.js → linear-DWpCiijk.js} +1 -1
- package/dist/assets/{logs-panel-y2i-7VQF.js → logs-panel-z3Z9lCbV.js} +1 -1
- package/dist/assets/{markdown-renderer-D8AmLSIR.js → markdown-renderer-Md8pHWxP.js} +1 -1
- package/dist/assets/mermaid-4DMBBIKO-Dn0v3H8Z.js +1 -0
- package/dist/assets/{mermaid-Caj4ROsO.js → mermaid-dAaJQU1M.js} +3 -3
- package/dist/assets/{mhchem-CJmb5HsA.js → mhchem-2XRJK9de.js} +1 -1
- package/dist/assets/{mindmap-definition-VGOIOE7T-BJ9zWUqW.js → mindmap-definition-VGOIOE7T-whTFv8Zv.js} +1 -1
- package/dist/assets/{name-cell-input-BthamWJY.js → name-cell-input-BGxKE7pD.js} +1 -1
- package/dist/assets/{number-overlay-editor-DIy8e1ST.js → number-overlay-editor-65UcMR52.js} +1 -1
- package/dist/assets/{packages-panel-DsF1uf9X.js → packages-panel-BheI3Whw.js} +1 -1
- package/dist/assets/{panels-aWY9-L83.js → panels-5zIgiTjO.js} +1 -1
- package/dist/assets/{pieDiagram-ADFJNKIX-Mf2FMnt9.js → pieDiagram-ADFJNKIX-4n07I4VV.js} +1 -1
- package/dist/assets/{precisionRound-CU2C3Vxx.js → precisionRound-C3fmBb6j.js} +1 -1
- package/dist/assets/{quadrantDiagram-AYHSOK5B-B04U71uV.js → quadrantDiagram-AYHSOK5B-CNm24EC2.js} +1 -1
- package/dist/assets/{react-plotly-D4UaXGJL.js → react-plotly-OyYr93y7.js} +1 -1
- package/dist/assets/{react-vega-CqegDZRQ.js → react-vega-BEiHA2e9.js} +1 -1
- package/dist/assets/react-vega-BrNLU7si.js +1 -0
- package/dist/assets/{readonly-python-code-C_8a4fwz.js → readonly-python-code-q8H4JtWe.js} +1 -1
- package/dist/assets/{renderShortcut-B1jzzLJw.js → renderShortcut-Xr6z-RjZ.js} +1 -1
- package/dist/assets/{requirementDiagram-UZGBJVZJ-oJlPs172.js → requirementDiagram-UZGBJVZJ-B7BwuJGh.js} +1 -1
- package/dist/assets/{run-page-DQU-eaKQ.js → run-page-BtgxUxdD.js} +1 -1
- package/dist/assets/{sankeyDiagram-TZEHDZUN-aplEbaHE.js → sankeyDiagram-TZEHDZUN-C8KpmdhC.js} +1 -1
- package/dist/assets/{scratchpad-panel-N4QLTtHb.js → scratchpad-panel-BZn63vOx.js} +1 -1
- package/dist/assets/{secrets-panel-vKKBtc8G.js → secrets-panel-CEMSgQv5.js} +1 -1
- package/dist/assets/{sequenceDiagram-WL72ISMW-WAUwGkkd.js → sequenceDiagram-WL72ISMW-D0_AcPzd.js} +1 -1
- package/dist/assets/{session-panel-Cof-5_26.js → session-panel-iRBC1bk4.js} +1 -1
- package/dist/assets/{slides-component-CeMnlG8H.js → slides-component-C0UAH9QZ.js} +1 -1
- package/dist/assets/{snippets-panel-WBcYsSsb.js → snippets-panel-paMvhw49.js} +1 -1
- package/dist/assets/{stateDiagram-FKZM4ZOC-DUDhr_Gg.js → stateDiagram-FKZM4ZOC-Dz_iVJd6.js} +1 -1
- package/dist/assets/stateDiagram-v2-4FDKWEC3-CupainMB.js +1 -0
- package/dist/assets/{terminal-CF-esPMT.js → terminal-BLSSaFMR.js} +1 -1
- package/dist/assets/{textarea-8F9GOEGf.js → textarea-B9TY02t9.js} +1 -1
- package/dist/assets/{time-EL4bnqqQ.js → time-CSCsAxXS.js} +1 -1
- package/dist/assets/{timeline-definition-IT6M3QCI-D93LYpWp.js → timeline-definition-IT6M3QCI-DPXEeoSm.js} +1 -1
- package/dist/assets/{tooltip-DxKBXCGp.js → tooltip-DqsDDLgU.js} +1 -1
- package/dist/assets/{tracing-DGYwY__a.js → tracing-DVD0lR_-.js} +1 -1
- package/dist/assets/{tracing-panel-BHnlOWW9.js → tracing-panel-D0p98UnG.js} +2 -2
- package/dist/assets/{tree-B8r7cwRm.js → tree-Hg81oJmp.js} +1 -1
- package/dist/assets/{useAddCell-Cx99GRHQ.js → useAddCell-C0mjPsjt.js} +1 -1
- package/dist/assets/{useCellActionButton-VRGP_KkG.js → useCellActionButton-DR2cYGwm.js} +1 -1
- package/dist/assets/{useDeleteCell-DHPNhAtW.js → useDeleteCell-DyGTLzfg.js} +1 -1
- package/dist/assets/{useDependencyPanelTab-UoJrnugs.js → useDependencyPanelTab-Dd7aOXV0.js} +1 -1
- package/dist/assets/{useInstallPackage-xrG_Tm9T.js → useInstallPackage-Co79H1lQ.js} +1 -1
- package/dist/assets/{useNotebookActions-BEKXbrFJ.js → useNotebookActions-DMf9_Eai.js} +1 -1
- package/dist/assets/{useSplitCell-h8RpNtuv.js → useSplitCell-dutfMkv3.js} +1 -1
- package/dist/assets/{utilities.esm-AIy-_q0N.js → utilities.esm-BREvtThv.js} +1 -1
- package/dist/assets/{vega-component-D4ZTpyiq.js → vega-component-7jd4fFCJ.js} +1 -1
- package/dist/assets/{vega-loader.browser-DXARUlxo.js → vega-loader.browser-BegSZk0G.js} +1 -1
- package/dist/assets/{write-secret-modal-BodBOJkR.js → write-secret-modal-DO-EOoNO.js} +1 -1
- package/dist/assets/{xychartDiagram-PRI3JC2R-C8jV7uCC.js → xychartDiagram-PRI3JC2R-DINfGlOV.js} +1 -1
- package/dist/index.html +56 -56
- package/package.json +1 -1
- package/src/components/pages/gallery-page.tsx +37 -6
- package/src/core/ai/context/providers/file.ts +1 -1
- package/src/core/static/__tests__/files.test.ts +195 -1
- package/src/core/static/files.ts +39 -9
- package/src/plugins/impl/anywidget/AnyWidgetPlugin.tsx +7 -1
- package/src/utils/__tests__/blob.test.ts +3 -3
- package/src/utils/blob.ts +14 -27
- package/dist/assets/blob-t6qcPM7K.js +0 -1
- package/dist/assets/channel-CUmF6tDU.js +0 -1
- package/dist/assets/classDiagram-2ON5EDUG-DLI68D-F.js +0 -1
- package/dist/assets/classDiagram-v2-WZHVMYZB-yfw4NTdf.js +0 -1
- package/dist/assets/gallery-page-Yq7Go5FK.js +0 -1
- package/dist/assets/index-BTVKRPtt.css +0 -2
- package/dist/assets/katex-DF982Ty5.js +0 -1
- package/dist/assets/mermaid-4DMBBIKO-DQz_QvBC.js +0 -1
- package/dist/assets/react-vega-CP7NqbRQ.js +0 -1
- package/dist/assets/stateDiagram-v2-4FDKWEC3-yH9Rugj-.js +0 -1
- /package/dist/assets/{alert-BOoN6gJ1.js → alert-Cx8eFRUM.js} +0 -0
- /package/dist/assets/{cell-link-BoOn0OpK.js → cell-link-DfoJF6Bq.js} +0 -0
- /package/dist/assets/{copy-DHrHayPa.js → copy-BaRrAFL-.js} +0 -0
- /package/dist/assets/{defaultLocale-BLne0bXb.js → defaultLocale-B6z1Qyqt.js} +0 -0
- /package/dist/assets/{defaultLocale-JieDVWC_.js → defaultLocale-YteS-k_t.js} +0 -0
- /package/dist/assets/{dist-CDXJRSCj.js → dist-BMEHQAhk.js} +0 -0
- /package/dist/assets/{emotion-is-prop-valid.esm-C59xfSYt.js → emotion-is-prop-valid.esm-Dangy3Bv.js} +0 -0
- /package/dist/assets/{error-banner-Dlrzo_Ay.js → error-banner-w4pz2qUB.js} +0 -0
- /package/dist/assets/{extends-BiFDv3jB.js → extends-Dqvpuc10.js} +0 -0
- /package/dist/assets/{focus-BEf2RhRf.js → focus-RQ0afibT.js} +0 -0
- /package/dist/assets/{html-to-image-DrmKVKna.js → html-to-image-BIY1TtH0.js} +0 -0
- /package/dist/assets/{katex-CDLTCvjQ.js → katex-CbllUrnh.js} +0 -0
- /package/dist/assets/{kbd-Cm6Ba9qg.js → kbd-k3Sn_RwW.js} +0 -0
- /package/dist/assets/{links-7AQBmdyV.js → links-fh_IXIKE.js} +0 -0
- /package/dist/assets/{multi-map-t2yhdp8D.js → multi-map-A4XNra08.js} +0 -0
- /package/dist/assets/{objectWithoutPropertiesLoose-DfWeGRFv.js → objectWithoutPropertiesLoose-DoKw85w0.js} +0 -0
- /package/dist/assets/{ordinal-C93T4L8H.js → ordinal-DAqJmfoU.js} +0 -0
- /package/dist/assets/{process-output-OTqBNunj.js → process-output-C77tRi36.js} +0 -0
- /package/dist/assets/{prop-types-DaaA-ptl.js → prop-types-DVDiRdwc.js} +0 -0
- /package/dist/assets/{purify.es-DZrAQFIu.js → purify.es-B-nzWya6.js} +0 -0
- /package/dist/assets/{range-1DwpgXvM.js → range-7fnH_zLA.js} +0 -0
- /package/dist/assets/{table-DScsXgJW.js → table-BOsFCeLh.js} +0 -0
- /package/dist/assets/{useAsyncData-BMGLSTg8.js → useAsyncData-CgmD3hjw.js} +0 -0
- /package/dist/assets/{useDeepCompareMemoize-ChxLMT9E.js → useDeepCompareMemoize-CFtQU7An.js} +0 -0
- /package/dist/assets/{useIframeCapabilities-B_pQb20b.js → useIframeCapabilities-CC8VH6kZ.js} +0 -0
- /package/dist/assets/{useRunCells-BOowME8Z.js → useRunCells-BJznEpzj.js} +0 -0
|
@@ -33,6 +33,15 @@ const tabTarget = (path: string): string => {
|
|
|
33
33
|
return `${getSessionId()}-${encodeURIComponent(path)}`;
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
+
const isHttpsUrl = (value: string): boolean => {
|
|
37
|
+
try {
|
|
38
|
+
const url = new URL(value);
|
|
39
|
+
return url.protocol === "https:";
|
|
40
|
+
} catch {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
36
45
|
const SEARCH_THRESHOLD = 10;
|
|
37
46
|
|
|
38
47
|
const GalleryPage: React.FC = () => {
|
|
@@ -43,10 +52,10 @@ const GalleryPage: React.FC = () => {
|
|
|
43
52
|
[],
|
|
44
53
|
);
|
|
45
54
|
const workspace = response.data;
|
|
46
|
-
const files = workspace?.files ?? [];
|
|
47
|
-
const root = workspace?.root ?? "";
|
|
48
55
|
|
|
49
56
|
const formattedFiles = useMemo(() => {
|
|
57
|
+
const files = workspace?.files ?? [];
|
|
58
|
+
const root = workspace?.root ?? "";
|
|
50
59
|
return files
|
|
51
60
|
.filter((file) => !file.isDirectory)
|
|
52
61
|
.map((file) => {
|
|
@@ -54,17 +63,28 @@ const GalleryPage: React.FC = () => {
|
|
|
54
63
|
root && Paths.isAbsolute(file.path) && file.path.startsWith(root)
|
|
55
64
|
? Paths.rest(file.path, root)
|
|
56
65
|
: file.path;
|
|
57
|
-
const title =
|
|
66
|
+
const title =
|
|
67
|
+
file.opengraph?.title ?? titleCase(Paths.basename(relativePath));
|
|
58
68
|
const subtitle = titleCase(Paths.dirname(relativePath));
|
|
69
|
+
const description = file.opengraph?.description ?? "";
|
|
70
|
+
const opengraphImage = file.opengraph?.image;
|
|
71
|
+
const thumbnailUrl =
|
|
72
|
+
opengraphImage && isHttpsUrl(opengraphImage)
|
|
73
|
+
? opengraphImage
|
|
74
|
+
: asURL(
|
|
75
|
+
`/og/thumbnail?file=${encodeURIComponent(relativePath)}`,
|
|
76
|
+
).toString();
|
|
59
77
|
return {
|
|
60
78
|
...file,
|
|
61
79
|
relativePath,
|
|
62
80
|
title,
|
|
63
81
|
subtitle,
|
|
82
|
+
description,
|
|
83
|
+
thumbnailUrl,
|
|
64
84
|
};
|
|
65
85
|
})
|
|
66
86
|
.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
|
|
67
|
-
}, [files, root]);
|
|
87
|
+
}, [workspace?.files, workspace?.root]);
|
|
68
88
|
|
|
69
89
|
const filteredFiles = useMemo(() => {
|
|
70
90
|
if (!searchQuery) {
|
|
@@ -130,8 +150,14 @@ const GalleryPage: React.FC = () => {
|
|
|
130
150
|
target={tabTarget(file.path)}
|
|
131
151
|
className="no-underline"
|
|
132
152
|
>
|
|
133
|
-
<Card className="h-full hover:bg-accent/20 transition-colors">
|
|
134
|
-
<
|
|
153
|
+
<Card className="h-full overflow-hidden hover:bg-accent/20 transition-colors">
|
|
154
|
+
<img
|
|
155
|
+
src={file.thumbnailUrl}
|
|
156
|
+
alt={file.title}
|
|
157
|
+
loading="lazy"
|
|
158
|
+
className="w-full aspect-1200/630 object-cover border-b border-border/60"
|
|
159
|
+
/>
|
|
160
|
+
<CardContent className="p-6 pt-4">
|
|
135
161
|
<div className="flex flex-col gap-1">
|
|
136
162
|
{file.subtitle && (
|
|
137
163
|
<div className="text-sm font-semibold text-muted-foreground">
|
|
@@ -141,6 +167,11 @@ const GalleryPage: React.FC = () => {
|
|
|
141
167
|
<div className="text-lg font-medium">
|
|
142
168
|
{file.title}
|
|
143
169
|
</div>
|
|
170
|
+
{file.description && (
|
|
171
|
+
<div className="text-sm text-muted-foreground line-clamp-3 mt-1">
|
|
172
|
+
{file.description}
|
|
173
|
+
</div>
|
|
174
|
+
)}
|
|
144
175
|
</div>
|
|
145
176
|
</CardContent>
|
|
146
177
|
</Card>
|
|
@@ -237,7 +237,7 @@ export class FileContextProvider extends AIContextProvider<FileContextItem> {
|
|
|
237
237
|
fileDetails.contents as Base64String,
|
|
238
238
|
mimeType,
|
|
239
239
|
);
|
|
240
|
-
blob =
|
|
240
|
+
blob = deserializeBlob(dataURL);
|
|
241
241
|
} catch {
|
|
242
242
|
// Fallback to treating as text
|
|
243
243
|
blob = new Blob([fileDetails.contents], { type: mimeType });
|
|
@@ -6,7 +6,7 @@ import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
|
|
|
6
6
|
import { createLoader } from "@/plugins/impl/vega/vega-loader";
|
|
7
7
|
import { Functions } from "@/utils/functions";
|
|
8
8
|
import type { DataURLString } from "@/utils/json/base64";
|
|
9
|
-
import { patchFetch, patchVegaLoader } from "../files";
|
|
9
|
+
import { patchFetch, patchVegaLoader, resolveVirtualFileURL } from "../files";
|
|
10
10
|
|
|
11
11
|
// Start a tiny server to serve virtual files
|
|
12
12
|
const server = http.createServer((request, response) => {
|
|
@@ -350,6 +350,181 @@ describe("patchVegaLoader - loader.load", () => {
|
|
|
350
350
|
});
|
|
351
351
|
});
|
|
352
352
|
|
|
353
|
+
describe("resolveVirtualFileURL", () => {
|
|
354
|
+
// Mock URL.createObjectURL for jsdom environment
|
|
355
|
+
const mockBlobURLs = new Map<string, Blob>();
|
|
356
|
+
let blobCounter = 0;
|
|
357
|
+
|
|
358
|
+
beforeAll(() => {
|
|
359
|
+
URL.createObjectURL = vi.fn((blob: Blob) => {
|
|
360
|
+
const url = `blob:test-${blobCounter++}`;
|
|
361
|
+
mockBlobURLs.set(url, blob);
|
|
362
|
+
return url;
|
|
363
|
+
});
|
|
364
|
+
URL.revokeObjectURL = vi.fn((url: string) => {
|
|
365
|
+
mockBlobURLs.delete(url);
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
afterAll(() => {
|
|
370
|
+
mockBlobURLs.clear();
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
it("should return a blob URL for virtual files", () => {
|
|
374
|
+
const virtualFiles = {
|
|
375
|
+
"/@file/widget.js":
|
|
376
|
+
"data:text/javascript;base64,ZXhwb3J0IGRlZmF1bHQgeyByZW5kZXI6ICgpID0+IHt9IH0=" as DataURLString,
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
const result = resolveVirtualFileURL("/@file/widget.js", virtualFiles);
|
|
380
|
+
|
|
381
|
+
expect(result).toMatch(/^blob:/);
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
it("should return the original URL for non-virtual files", () => {
|
|
385
|
+
const virtualFiles = {};
|
|
386
|
+
|
|
387
|
+
const result = resolveVirtualFileURL(
|
|
388
|
+
"http://example.com/widget.js",
|
|
389
|
+
virtualFiles,
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
expect(result).toBe("http://example.com/widget.js");
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
it("should handle various URL formats", () => {
|
|
396
|
+
const virtualFiles = {
|
|
397
|
+
"/@file/module.js":
|
|
398
|
+
"data:text/javascript;base64,Y29uc29sZS5sb2coJ3Rlc3QnKQ==" as DataURLString,
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
const testUrls = [
|
|
402
|
+
"/@file/module.js",
|
|
403
|
+
"./@file/module.js",
|
|
404
|
+
"http://example.com/@file/module.js",
|
|
405
|
+
];
|
|
406
|
+
|
|
407
|
+
for (const url of testUrls) {
|
|
408
|
+
const result = resolveVirtualFileURL(url, virtualFiles);
|
|
409
|
+
expect(result).toMatch(/^blob:/);
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
it("should create blob URL with correct content", async () => {
|
|
414
|
+
const jsCode = "export default { render: () => {} }";
|
|
415
|
+
const base64Code = btoa(jsCode);
|
|
416
|
+
const virtualFiles = {
|
|
417
|
+
"/@file/test-module.js":
|
|
418
|
+
`data:text/javascript;base64,${base64Code}` as DataURLString,
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
const blobUrl = resolveVirtualFileURL(
|
|
422
|
+
"/@file/test-module.js",
|
|
423
|
+
virtualFiles,
|
|
424
|
+
);
|
|
425
|
+
|
|
426
|
+
expect(blobUrl).toMatch(/^blob:/);
|
|
427
|
+
expect(URL.createObjectURL).toHaveBeenCalled();
|
|
428
|
+
|
|
429
|
+
// Verify blob content through the mock
|
|
430
|
+
const blob = mockBlobURLs.get(blobUrl);
|
|
431
|
+
expect(blob).toBeDefined();
|
|
432
|
+
const text = await blob!.text();
|
|
433
|
+
expect(text).toBe(jsCode);
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
it("should handle file:// URLs with @file/ paths", () => {
|
|
437
|
+
const virtualFiles = {
|
|
438
|
+
"/@file/local-module.js":
|
|
439
|
+
"data:text/javascript;base64,ZXhwb3J0IGRlZmF1bHQge30=" as DataURLString,
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
const result = resolveVirtualFileURL(
|
|
443
|
+
"file:///Users/test/@file/local-module.js",
|
|
444
|
+
virtualFiles,
|
|
445
|
+
);
|
|
446
|
+
|
|
447
|
+
expect(result).toMatch(/^blob:/);
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
it("should handle different MIME types", async () => {
|
|
451
|
+
const virtualFiles = {
|
|
452
|
+
"/@file/script.js":
|
|
453
|
+
"data:application/javascript;base64,Y29uc3QgeCA9IDE=" as DataURLString,
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
const blobUrl = resolveVirtualFileURL("/@file/script.js", virtualFiles);
|
|
457
|
+
|
|
458
|
+
// Should still be a valid blob URL
|
|
459
|
+
expect(blobUrl).toMatch(/^blob:/);
|
|
460
|
+
|
|
461
|
+
// Verify blob content through the mock
|
|
462
|
+
const blob = mockBlobURLs.get(blobUrl);
|
|
463
|
+
expect(blob).toBeDefined();
|
|
464
|
+
const text = await blob!.text();
|
|
465
|
+
expect(text).toBe("const x = 1");
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
it("should handle blob: base URIs correctly", () => {
|
|
469
|
+
// Mock document.baseURI to simulate blob: protocol
|
|
470
|
+
const originalBaseURI = document.baseURI;
|
|
471
|
+
Object.defineProperty(document, "baseURI", {
|
|
472
|
+
value: "blob:https://example.com/uuid",
|
|
473
|
+
configurable: true,
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
const virtualFiles = {
|
|
477
|
+
"/@file/blob-module.js":
|
|
478
|
+
"data:text/javascript;base64,ZXhwb3J0IGRlZmF1bHQge30=" as DataURLString,
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
const result = resolveVirtualFileURL("/@file/blob-module.js", virtualFiles);
|
|
482
|
+
|
|
483
|
+
expect(result).toMatch(/^blob:/);
|
|
484
|
+
|
|
485
|
+
// Restore original baseURI
|
|
486
|
+
Object.defineProperty(document, "baseURI", {
|
|
487
|
+
value: originalBaseURI,
|
|
488
|
+
configurable: true,
|
|
489
|
+
});
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
it("should handle data URLs with no explicit MIME type", async () => {
|
|
493
|
+
const virtualFiles = {
|
|
494
|
+
"/@file/generic.bin": "data:;base64,SGVsbG8gV29ybGQ=" as DataURLString,
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
const blobUrl = resolveVirtualFileURL("/@file/generic.bin", virtualFiles);
|
|
498
|
+
expect(blobUrl).toMatch(/^blob:/);
|
|
499
|
+
|
|
500
|
+
// Verify blob content through the mock
|
|
501
|
+
const blob = mockBlobURLs.get(blobUrl);
|
|
502
|
+
expect(blob).toBeDefined();
|
|
503
|
+
const text = await blob!.text();
|
|
504
|
+
expect(text).toBe("Hello World");
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
it("should match URLs with prefix paths before /@file/", async () => {
|
|
508
|
+
const virtualFiles = {
|
|
509
|
+
"/@file/4263-66-yUGhgQXp.js":
|
|
510
|
+
"data:application/javascript;base64,ZnVuY3Rpb24gcmVuZGVyKCkge30=" as DataURLString,
|
|
511
|
+
};
|
|
512
|
+
|
|
513
|
+
const blobUrl = resolveVirtualFileURL(
|
|
514
|
+
"https://molab.marimo.app/preview/@file/4263-66-yUGhgQXp.js",
|
|
515
|
+
virtualFiles,
|
|
516
|
+
);
|
|
517
|
+
|
|
518
|
+
expect(blobUrl).toMatch(/^blob:/);
|
|
519
|
+
|
|
520
|
+
// Verify blob content through the mock
|
|
521
|
+
const blob = mockBlobURLs.get(blobUrl);
|
|
522
|
+
expect(blob).toBeDefined();
|
|
523
|
+
const text = await blob!.text();
|
|
524
|
+
expect(text).toBe("function render() {}");
|
|
525
|
+
});
|
|
526
|
+
});
|
|
527
|
+
|
|
353
528
|
describe("maybeGetVirtualFile utility function", () => {
|
|
354
529
|
it("should handle URLs without leading dots correctly", async () => {
|
|
355
530
|
const virtualFiles = {
|
|
@@ -370,6 +545,25 @@ describe("maybeGetVirtualFile utility function", () => {
|
|
|
370
545
|
expect(text2).toBe("test");
|
|
371
546
|
});
|
|
372
547
|
|
|
548
|
+
it("should match URLs with prefix paths before /@file/", async () => {
|
|
549
|
+
const virtualFiles = {
|
|
550
|
+
"/@file/4263-66-yUGhgQXp.js":
|
|
551
|
+
"data:application/javascript;base64,ZnVuY3Rpb24gcmVuZGVyKCkge30=" as DataURLString,
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
const unpatch = patchFetch(virtualFiles);
|
|
555
|
+
|
|
556
|
+
// Test URL with a prefix path before /@file/
|
|
557
|
+
const response = await window.fetch(
|
|
558
|
+
"https://molab.marimo.app/preview/@file/4263-66-yUGhgQXp.js",
|
|
559
|
+
);
|
|
560
|
+
const text = await response.text();
|
|
561
|
+
|
|
562
|
+
expect(text).toBe("function render() {}");
|
|
563
|
+
|
|
564
|
+
unpatch();
|
|
565
|
+
});
|
|
566
|
+
|
|
373
567
|
it("should handle complex file:// URLs with nested paths", async () => {
|
|
374
568
|
const virtualFiles = {
|
|
375
569
|
"/@file/nested/data.json":
|
package/src/core/static/files.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
3
|
import type { Loader } from "@/plugins/impl/vega/vega-loader";
|
|
4
|
+
import { deserializeBlob } from "@/utils/blob";
|
|
5
|
+
import type { DataURLString } from "@/utils/json/base64";
|
|
4
6
|
import { Logger } from "@/utils/Logger";
|
|
5
7
|
import { getStaticVirtualFiles } from "./static-state";
|
|
6
8
|
import type { StaticVirtualFiles } from "./types";
|
|
@@ -120,6 +122,24 @@ function withoutLeadingDot(path: string): string {
|
|
|
120
122
|
return path.startsWith(".") ? path.slice(1) : path;
|
|
121
123
|
}
|
|
122
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Resolve a URL to a blob URL if it's a virtual file, for use with dynamic import().
|
|
127
|
+
* Unlike fetch, import() can't be patched, so we need to convert data URLs to blob URLs.
|
|
128
|
+
*
|
|
129
|
+
* @returns The original URL if not a virtual file, or a blob URL if it is
|
|
130
|
+
*/
|
|
131
|
+
export function resolveVirtualFileURL(
|
|
132
|
+
url: string,
|
|
133
|
+
files: StaticVirtualFiles = getStaticVirtualFiles(),
|
|
134
|
+
): string {
|
|
135
|
+
const vfile = maybeGetVirtualFile(url, files);
|
|
136
|
+
if (!vfile) {
|
|
137
|
+
return url;
|
|
138
|
+
}
|
|
139
|
+
const blob = deserializeBlob(vfile as DataURLString);
|
|
140
|
+
return URL.createObjectURL(blob);
|
|
141
|
+
}
|
|
142
|
+
|
|
123
143
|
function maybeGetVirtualFile(
|
|
124
144
|
url: string,
|
|
125
145
|
files: StaticVirtualFiles,
|
|
@@ -130,14 +150,11 @@ function maybeGetVirtualFile(
|
|
|
130
150
|
}
|
|
131
151
|
const pathname = new URL(url, base).pathname;
|
|
132
152
|
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
url = url.slice(indexOfFile);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
153
|
+
// Extract the /@file/... suffix from the URL or pathname
|
|
154
|
+
// This handles URLs like https://example.com/prefix/@file/foo.js
|
|
155
|
+
// or file:///path/to/@file/foo.js
|
|
156
|
+
const filePathFromUrl = extractFilePath(url);
|
|
157
|
+
const filePathFromPathname = extractFilePath(pathname);
|
|
141
158
|
|
|
142
159
|
// Few variations to grab the URL.
|
|
143
160
|
// This can happen if a static file was open at file:// or https://
|
|
@@ -145,6 +162,19 @@ function maybeGetVirtualFile(
|
|
|
145
162
|
files[url] ||
|
|
146
163
|
files[withoutLeadingDot(url)] ||
|
|
147
164
|
files[pathname] ||
|
|
148
|
-
files[withoutLeadingDot(pathname)]
|
|
165
|
+
files[withoutLeadingDot(pathname)] ||
|
|
166
|
+
(filePathFromUrl && files[filePathFromUrl]) ||
|
|
167
|
+
(filePathFromPathname && files[filePathFromPathname])
|
|
149
168
|
);
|
|
150
169
|
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Extract the /@file/... path from a URL string
|
|
173
|
+
*/
|
|
174
|
+
function extractFilePath(url: string): string | null {
|
|
175
|
+
const indexOfFile = url.indexOf("/@file/");
|
|
176
|
+
if (indexOfFile !== -1) {
|
|
177
|
+
return url.slice(indexOfFile);
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
@@ -8,6 +8,8 @@ import useEvent from "react-use-event-hook";
|
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
import { MarimoIncomingMessageEvent } from "@/core/dom/events";
|
|
10
10
|
import { asRemoteURL } from "@/core/runtime/config";
|
|
11
|
+
import { resolveVirtualFileURL } from "@/core/static/files";
|
|
12
|
+
import { isStaticNotebook } from "@/core/static/static-state";
|
|
11
13
|
import { useAsyncData } from "@/hooks/useAsyncData";
|
|
12
14
|
import { useDeepCompareMemoize } from "@/hooks/useDeepCompareMemoize";
|
|
13
15
|
import {
|
|
@@ -93,7 +95,11 @@ const AnyWidgetSlot = (
|
|
|
93
95
|
error,
|
|
94
96
|
refetch,
|
|
95
97
|
} = useAsyncData(async () => {
|
|
96
|
-
|
|
98
|
+
let url = asRemoteURL(jsUrl).toString();
|
|
99
|
+
// In static notebooks, resolve virtual files to blob URLs for import()
|
|
100
|
+
if (isStaticNotebook()) {
|
|
101
|
+
url = resolveVirtualFileURL(url);
|
|
102
|
+
}
|
|
97
103
|
return await import(/* @vite-ignore */ url);
|
|
98
104
|
// Re-render on jsHash change (which is a hash of the contents of the file)
|
|
99
105
|
// instead of a jsUrl change because URLs may change without the contents
|
|
@@ -20,7 +20,7 @@ describe("Blob serialization and deserialization", () => {
|
|
|
20
20
|
|
|
21
21
|
test("deserializeBlob should deserialize a base64 string to a Blob", async () => {
|
|
22
22
|
const serialized = await serializeBlob(testBlob);
|
|
23
|
-
const deserialized =
|
|
23
|
+
const deserialized = deserializeBlob(serialized);
|
|
24
24
|
expect(deserialized).toBeDefined();
|
|
25
25
|
expect(deserialized.size).toBe(testBlob.size);
|
|
26
26
|
expect(deserialized.type).toBe(testBlob.type);
|
|
@@ -28,7 +28,7 @@ describe("Blob serialization and deserialization", () => {
|
|
|
28
28
|
|
|
29
29
|
test("deserialized Blob should contain the original content", async () => {
|
|
30
30
|
const serialized = await serializeBlob(testBlob);
|
|
31
|
-
const deserialized =
|
|
31
|
+
const deserialized = deserializeBlob(serialized);
|
|
32
32
|
const reader = new FileReader();
|
|
33
33
|
// eslint-disable-next-line unicorn/prefer-blob-reading-methods
|
|
34
34
|
reader.readAsText(deserialized);
|
|
@@ -45,7 +45,7 @@ describe("Blob serialization and deserialization", () => {
|
|
|
45
45
|
type: "image/png",
|
|
46
46
|
});
|
|
47
47
|
const serialized = await serializeBlob(imageBlob);
|
|
48
|
-
const deserialized =
|
|
48
|
+
const deserialized = deserializeBlob(serialized);
|
|
49
49
|
expect(deserialized).toBeDefined();
|
|
50
50
|
expect(deserialized.size).toBe(imageBlob.size);
|
|
51
51
|
expect(deserialized.type).toBe(imageBlob.type);
|
package/src/utils/blob.ts
CHANGED
|
@@ -14,32 +14,19 @@ export function serializeBlob<T>(blob: Blob): Promise<DataURLString> {
|
|
|
14
14
|
});
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export function deserializeBlob(serializedBlob: DataURLString):
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
for (let i = 0; i < len; i++) {
|
|
29
|
-
bytes[i] = binaryString.charCodeAt(i);
|
|
30
|
-
}
|
|
31
|
-
// Create a new Blob from the array buffer
|
|
32
|
-
const blob = new Blob([bytes], { type: mimeType });
|
|
33
|
-
resolve(blob);
|
|
34
|
-
} catch (error) {
|
|
35
|
-
reject(ensureError(error));
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function ensureError(error: unknown): Error {
|
|
41
|
-
if (error instanceof Error) {
|
|
42
|
-
return error;
|
|
17
|
+
export function deserializeBlob(serializedBlob: DataURLString): Blob {
|
|
18
|
+
// Extract the base64 data from the data URL
|
|
19
|
+
const [prefix, base64Data] = serializedBlob.split(",", 2);
|
|
20
|
+
const mimeType = /^data:(.+);base64$/.exec(prefix)?.[1];
|
|
21
|
+
// Decode the base64 string
|
|
22
|
+
const binaryString = atob(base64Data);
|
|
23
|
+
// Convert the binary string to an array buffer
|
|
24
|
+
const len = binaryString.length;
|
|
25
|
+
const bytes = new Uint8Array(len);
|
|
26
|
+
for (let i = 0; i < len; i++) {
|
|
27
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
43
28
|
}
|
|
44
|
-
|
|
29
|
+
// Create a new Blob from the array buffer
|
|
30
|
+
const blob = new Blob([bytes], { type: mimeType });
|
|
31
|
+
return blob;
|
|
45
32
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
function u(r){return new Promise((a,i)=>{let t=new FileReader;t.onload=e=>{var n;a((n=e.target)==null?void 0:n.result)},t.onerror=e=>{i(Error(`Failed to read blob: ${e.type}`))},t.readAsDataURL(r)})}function b(r){return new Promise((a,i)=>{var t;try{let[e,n]=r.split(",",2),d=(t=/^data:(.+);base64$/.exec(e))==null?void 0:t[1],l=atob(n),s=l.length,c=new Uint8Array(s);for(let o=0;o<s;o++)c[o]=l.charCodeAt(o);a(new Blob([c],{type:d}))}catch(e){i(f(e))}})}function f(r){return r instanceof Error?r:Error(`${r}`)}export{u as n,b as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{et as r,tt as e}from"./chunk-ABZYJK2D-CtRGq-db.js";var o=(t,a)=>e.lang.round(r.parse(t)[a]);export{o as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./purify.es-DZrAQFIu.js";import"./src-DJ8ZKoFs.js";import"./chunk-S3R3BYOJ-CM-pQ0EF.js";import{n as t}from"./src-CmKhyEBC.js";import"./chunk-ABZYJK2D-CtRGq-db.js";import"./chunk-HN2XXSSU-BBxJMYrA.js";import"./chunk-CVBHYZKI-Brsoob-W.js";import"./chunk-ATLVNIR6-CXEe2jMF.js";import"./dist-DxxvVPQH.js";import"./chunk-JA3XYJ7Z-B5-JYmoA.js";import"./chunk-JZLCHNYA-UFlatyc1.js";import"./chunk-QXUST7PY-CbBaWlhv.js";import"./chunk-N4CR4FBY-BFF_Z7sG.js";import"./chunk-FMBD7UC4-kejklSRQ.js";import"./chunk-55IACEB6-NZRDKuqH.js";import"./chunk-QN33PNHL-DOgXIePg.js";import{i,n as o,r as m,t as p}from"./chunk-B4BG7PRW-BVqt-NSK.js";var a={parser:o,get db(){return new p},renderer:m,styles:i,init:t(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{a as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./purify.es-DZrAQFIu.js";import"./src-DJ8ZKoFs.js";import"./chunk-S3R3BYOJ-CM-pQ0EF.js";import{n as t}from"./src-CmKhyEBC.js";import"./chunk-ABZYJK2D-CtRGq-db.js";import"./chunk-HN2XXSSU-BBxJMYrA.js";import"./chunk-CVBHYZKI-Brsoob-W.js";import"./chunk-ATLVNIR6-CXEe2jMF.js";import"./dist-DxxvVPQH.js";import"./chunk-JA3XYJ7Z-B5-JYmoA.js";import"./chunk-JZLCHNYA-UFlatyc1.js";import"./chunk-QXUST7PY-CbBaWlhv.js";import"./chunk-N4CR4FBY-BFF_Z7sG.js";import"./chunk-FMBD7UC4-kejklSRQ.js";import"./chunk-55IACEB6-NZRDKuqH.js";import"./chunk-QN33PNHL-DOgXIePg.js";import{i,n as o,r as m,t as p}from"./chunk-B4BG7PRW-BVqt-NSK.js";var a={parser:o,get db(){return new p},renderer:m,styles:i,init:t(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{a as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as x}from"./chunk-LvLJmgfZ.js";import"./useEvent-BhXAndur.js";import{t as v}from"./react-Bj1aDYRI.js";import"./react-dom-CSu739Rf.js";import"./compiler-runtime-B3qBwwSJ.js";import{t as b}from"./ErrorBoundary-B9Ifj8Jf.js";import{t as w}from"./jsx-runtime-ZmTK25f3.js";import{r as C}from"./requests-B4FYHTZl.js";import{t as u}from"./spinner-DA8-7wQv.js";import{lt as k,r as S}from"./input-DHHmNa19.js";import{n,t as P}from"./paths-Dfii2bN8.js";import{c as M,t as $}from"./session-fBtIbMpB.js";import"./Combination-izwufzWe.js";import{r as y}from"./errors-CPlNr33a.js";import{t as p}from"./error-banner-Dlrzo_Ay.js";import{n as z}from"./useAsyncData-BMGLSTg8.js";import{n as L,t as U}from"./card-DdlNjkEA.js";var c=x(v(),1),r=x(w(),1),A=s=>s.charAt(0).toUpperCase()+s.slice(1).toLowerCase(),g=s=>{let o=P.guessDeliminator(s).deliminator;return s.replace(/\.[^./]+$/,"").split(o).filter(Boolean).map(d=>d.split(/[_-]/).map(A).join(" ")).join(" > ")},D=s=>`${$()}-${encodeURIComponent(s)}`,I=10,R=()=>{let{getWorkspaceFiles:s}=C(),[o,d]=(0,c.useState)(""),l=z(()=>s({includeMarkdown:!1}),[]),a=l.data,h=(a==null?void 0:a.files)??[],i=(a==null?void 0:a.root)??"",m=(0,c.useMemo)(()=>h.filter(e=>!e.isDirectory).map(e=>{let t=i&&n.isAbsolute(e.path)&&e.path.startsWith(i)?n.rest(e.path,i):e.path,j=g(n.basename(t)),N=g(n.dirname(t));return{...e,relativePath:t,title:j,subtitle:N}}).sort((e,t)=>e.relativePath.localeCompare(t.relativePath)),[h,i]),f=(0,c.useMemo)(()=>{if(!o)return m;let e=o.toLowerCase();return m.filter(t=>t.title.toLowerCase().includes(e))},[m,o]);return l.isPending?(0,r.jsx)(u,{centered:!0,size:"xlarge",className:"mt-6"}):l.error?(0,r.jsx)(p,{kind:"danger",className:"rounded p-4",children:y(l.error)}):a?(0,r.jsx)(c.Suspense,{children:(0,r.jsxs)("div",{className:"flex flex-col gap-6 max-w-6xl container pt-5 pb-20 z-10",children:[(0,r.jsx)("img",{src:"logo.png",alt:"marimo logo",className:"w-48 mb-2"}),(0,r.jsx)(b,{children:(0,r.jsxs)("div",{className:"flex flex-col gap-2",children:[a.hasMore&&(0,r.jsxs)(p,{kind:"warn",className:"rounded p-4",children:["Showing first ",a.fileCount," files. Your workspace has more files."]}),m.length>I&&(0,r.jsx)(S,{id:"search",value:o,icon:(0,r.jsx)(k,{className:"h-4 w-4"}),onChange:e=>d(e.target.value),placeholder:"Search",rootClassName:"mb-3",className:"mb-0 border-border"}),f.length===0?(0,r.jsx)(p,{kind:"warn",className:"rounded p-4",children:"No marimo apps found."}):(0,r.jsx)("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4",children:f.map(e=>(0,r.jsx)("a",{href:M(`?file=${encodeURIComponent(e.relativePath)}`).toString(),target:D(e.path),className:"no-underline",children:(0,r.jsx)(U,{className:"h-full hover:bg-accent/20 transition-colors",children:(0,r.jsx)(L,{className:"p-6",children:(0,r.jsxs)("div",{className:"flex flex-col gap-1",children:[e.subtitle&&(0,r.jsx)("div",{className:"text-sm font-semibold text-muted-foreground",children:e.subtitle}),(0,r.jsx)("div",{className:"text-lg font-medium",children:e.title})]})})})},e.path))})]})})]})}):(0,r.jsx)(u,{centered:!0,size:"xlarge",className:"mt-6"})};export{R as default};
|