@marimo-team/frontend 0.23.10-dev42 → 0.23.10-dev43

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.
@@ -1,11 +1,15 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
- import { renderHook, waitFor } from "@testing-library/react";
3
+ import { act, renderHook, waitFor } from "@testing-library/react";
4
4
  import { createStore, Provider } from "jotai";
5
5
  import type { ReactNode } from "react";
6
6
  import * as React from "react";
7
7
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
8
- import { storageAtom, useStorageEntries } from "../state";
8
+ import {
9
+ storageAtom,
10
+ useStorageEntries,
11
+ useStoragePageFetcher,
12
+ } from "../state";
9
13
  import type { StorageEntry, StorageState } from "../types";
10
14
 
11
15
  const mockRequest = vi.fn();
@@ -175,13 +179,205 @@ describe("useStorageEntries", () => {
175
179
 
176
180
  it("should store fetched entries in the atom", async () => {
177
181
  const entries = [makeEntry({ path: "new.txt" })];
178
- mockRequest.mockResolvedValue({ entries });
182
+ mockRequest.mockResolvedValue({
183
+ entries,
184
+ next_page_token: "150",
185
+ });
179
186
 
180
187
  renderHook(() => useStorageEntries("ns", "sub/"), { wrapper });
181
188
 
182
189
  await waitFor(() => {
183
190
  const state = store.get(storageAtom);
184
191
  expect(state.entriesByPath.get("ns::sub/")).toEqual(entries);
192
+ expect(state.pageMetadataByPath.get("ns::sub/")?.nextPageToken).toBe(
193
+ "150",
194
+ );
195
+ });
196
+ });
197
+
198
+ it("should load more entries when a next page token exists", async () => {
199
+ const firstPage = [makeEntry({ path: "a.txt" })];
200
+ const secondPage = [makeEntry({ path: "b.txt" })];
201
+ mockRequest
202
+ .mockResolvedValueOnce({
203
+ entries: firstPage,
204
+ next_page_token: "150",
205
+ })
206
+ .mockResolvedValueOnce({
207
+ entries: secondPage,
208
+ next_page_token: null,
209
+ });
210
+
211
+ const { result } = renderHook(() => useStorageEntries("ns", "sub/"), {
212
+ wrapper,
213
+ });
214
+
215
+ await waitFor(() => {
216
+ expect(result.current.entries).toEqual(firstPage);
217
+ });
218
+ expect(result.current.hasMore).toBe(true);
219
+
220
+ await act(async () => {
221
+ await result.current.loadMore();
222
+ });
223
+
224
+ expect(result.current.entries).toEqual([...firstPage, ...secondPage]);
225
+ expect(result.current.hasMore).toBe(false);
226
+ expect(mockRequest).toHaveBeenLastCalledWith({
227
+ namespace: "ns",
228
+ prefix: "sub/",
229
+ limit: 150,
230
+ pageToken: "150",
231
+ });
232
+ });
233
+
234
+ it("should load more entries when the next page token is an empty string", async () => {
235
+ const firstPage = [makeEntry({ path: "a.txt" })];
236
+ const secondPage = [makeEntry({ path: "b.txt" })];
237
+ mockRequest
238
+ .mockResolvedValueOnce({
239
+ entries: firstPage,
240
+ next_page_token: "",
241
+ })
242
+ .mockResolvedValueOnce({
243
+ entries: secondPage,
244
+ next_page_token: null,
245
+ });
246
+
247
+ const { result } = renderHook(() => useStorageEntries("ns", "sub/"), {
248
+ wrapper,
249
+ });
250
+
251
+ await waitFor(() => {
252
+ expect(result.current.entries).toEqual(firstPage);
253
+ });
254
+ expect(result.current.hasMore).toBe(true);
255
+
256
+ await act(async () => {
257
+ await result.current.loadMore();
258
+ });
259
+
260
+ expect(result.current.entries).toEqual([...firstPage, ...secondPage]);
261
+ expect(result.current.hasMore).toBe(false);
262
+ expect(mockRequest).toHaveBeenLastCalledWith({
263
+ namespace: "ns",
264
+ prefix: "sub/",
265
+ limit: 150,
266
+ pageToken: "",
267
+ });
268
+ });
269
+
270
+ it("should ignore duplicate load more calls while a page is loading", async () => {
271
+ const firstPage = [makeEntry({ path: "a.txt" })];
272
+ const secondPage = [makeEntry({ path: "b.txt" })];
273
+ let resolveLoadMore!: (value: {
274
+ entries: StorageEntry[];
275
+ next_page_token: string | null;
276
+ }) => void;
277
+ const loadMorePromise = new Promise<{
278
+ entries: StorageEntry[];
279
+ next_page_token: string | null;
280
+ }>((resolve) => {
281
+ resolveLoadMore = resolve;
282
+ });
283
+ mockRequest
284
+ .mockResolvedValueOnce({
285
+ entries: firstPage,
286
+ next_page_token: "150",
287
+ })
288
+ .mockReturnValueOnce(loadMorePromise);
289
+
290
+ const { result } = renderHook(() => useStorageEntries("ns", "sub/"), {
291
+ wrapper,
292
+ });
293
+
294
+ await waitFor(() => {
295
+ expect(result.current.entries).toEqual(firstPage);
296
+ });
297
+
298
+ await act(async () => {
299
+ const firstLoad = result.current.loadMore();
300
+ const secondLoad = result.current.loadMore();
301
+
302
+ expect(mockRequest).toHaveBeenCalledTimes(2);
303
+ resolveLoadMore({
304
+ entries: secondPage,
305
+ next_page_token: null,
306
+ });
307
+ await Promise.all([firstLoad, secondLoad]);
308
+ });
309
+
310
+ expect(result.current.entries).toEqual([...firstPage, ...secondPage]);
311
+ expect(mockRequest).toHaveBeenCalledTimes(2);
312
+ });
313
+
314
+ it("should fetch arbitrary storage pages", async () => {
315
+ const firstPage = [makeEntry({ path: "folder/a.txt" })];
316
+ const secondPage = [makeEntry({ path: "folder/b.txt" })];
317
+ mockRequest
318
+ .mockResolvedValueOnce({
319
+ entries: firstPage,
320
+ next_page_token: "150",
321
+ })
322
+ .mockResolvedValueOnce({
323
+ entries: secondPage,
324
+ next_page_token: null,
325
+ });
326
+
327
+ const { result } = renderHook(() => useStoragePageFetcher(), {
328
+ wrapper,
329
+ });
330
+
331
+ await act(async () => {
332
+ await result.current({
333
+ namespace: "ns",
334
+ prefix: "folder/",
335
+ });
336
+ });
337
+ await act(async () => {
338
+ await result.current({
339
+ namespace: "ns",
340
+ prefix: "folder/",
341
+ pageToken: "150",
342
+ append: true,
343
+ });
344
+ });
345
+
346
+ expect(store.get(storageAtom).entriesByPath.get("ns::folder/")).toEqual([
347
+ ...firstPage,
348
+ ...secondPage,
349
+ ]);
350
+ expect(mockRequest).toHaveBeenLastCalledWith({
351
+ namespace: "ns",
352
+ prefix: "folder/",
353
+ limit: 150,
354
+ pageToken: "150",
355
+ });
356
+ });
357
+
358
+ it("should forward an empty string page token", async () => {
359
+ mockRequest.mockResolvedValue({
360
+ entries: [],
361
+ next_page_token: null,
362
+ });
363
+
364
+ const { result } = renderHook(() => useStoragePageFetcher(), {
365
+ wrapper,
366
+ });
367
+
368
+ await act(async () => {
369
+ await result.current({
370
+ namespace: "ns",
371
+ prefix: "folder/",
372
+ pageToken: "",
373
+ });
374
+ });
375
+
376
+ expect(mockRequest).toHaveBeenLastCalledWith({
377
+ namespace: "ns",
378
+ prefix: "folder/",
379
+ limit: 150,
380
+ pageToken: "",
185
381
  });
186
382
  });
187
383
  });
@@ -1,11 +1,15 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
3
  import { atom, useAtomValue } from "jotai";
4
+ import { useCallback, useRef, useState } from "react";
4
5
  import { useAsyncData } from "@/hooks/useAsyncData";
5
6
  import { createReducerAndAtoms } from "@/utils/createReducer";
6
7
  import type { NotificationMessageData } from "../kernel/messages";
7
8
  import type { VariableName } from "../variables/types";
8
- import { ListStorageEntries } from "./request-registry";
9
+ import {
10
+ ListStorageEntries,
11
+ type StorageEntriesResult,
12
+ } from "./request-registry";
9
13
  import type { StorageEntry, StorageState } from "./types";
10
14
  import {
11
15
  DEFAULT_FETCH_LIMIT,
@@ -18,6 +22,7 @@ function initialState(): StorageState {
18
22
  return {
19
23
  namespaces: [],
20
24
  entriesByPath: new Map(),
25
+ pageMetadataByPath: new Map(),
21
26
  };
22
27
  }
23
28
 
@@ -48,23 +53,48 @@ const {
48
53
  namespace: string;
49
54
  prefix: string | null | undefined;
50
55
  entries: StorageEntry[];
56
+ nextPageToken?: string | null;
57
+ append?: boolean;
51
58
  },
52
59
  ) => {
53
60
  const key = storagePathKey(opts.namespace, opts.prefix);
54
61
  const entriesByPath = new Map(state.entriesByPath);
55
- entriesByPath.set(key, opts.entries);
56
- return { ...state, entriesByPath };
62
+ const entries =
63
+ opts.append && entriesByPath.has(key)
64
+ ? [...(entriesByPath.get(key) ?? []), ...opts.entries]
65
+ : opts.entries;
66
+ entriesByPath.set(key, entries);
67
+
68
+ const pageMetadataByPath = new Map(state.pageMetadataByPath);
69
+ pageMetadataByPath.set(key, {
70
+ nextPageToken: opts.nextPageToken ?? null,
71
+ });
72
+ return {
73
+ ...state,
74
+ entriesByPath,
75
+ pageMetadataByPath,
76
+ };
57
77
  },
58
78
 
59
79
  clearNamespaceCache: (state, namespace: string) => {
60
80
  const entriesByPath = new Map(state.entriesByPath);
81
+ const pageMetadataByPath = new Map(state.pageMetadataByPath);
61
82
  const prefix = storageNamespacePrefix(namespace);
62
83
  for (const key of entriesByPath.keys()) {
63
84
  if (key.startsWith(prefix)) {
64
85
  entriesByPath.delete(key);
65
86
  }
66
87
  }
67
- return { ...state, entriesByPath };
88
+ for (const key of pageMetadataByPath.keys()) {
89
+ if (key.startsWith(prefix)) {
90
+ pageMetadataByPath.delete(key);
91
+ }
92
+ }
93
+ return {
94
+ ...state,
95
+ entriesByPath,
96
+ pageMetadataByPath,
97
+ };
68
98
  },
69
99
 
70
100
  filterFromVariables: (state, variableNames: VariableName[]) => {
@@ -93,38 +123,119 @@ export function useStorageActions() {
93
123
 
94
124
  export { storageAtom };
95
125
 
126
+ async function fetchStorageEntriesPage({
127
+ namespace,
128
+ prefix,
129
+ pageToken,
130
+ append,
131
+ setEntries,
132
+ }: {
133
+ namespace: string;
134
+ prefix: string | null | undefined;
135
+ pageToken?: string | null;
136
+ append?: boolean;
137
+ setEntries: ReturnType<typeof useStorageActions>["setEntries"];
138
+ }): Promise<StorageEntriesResult> {
139
+ const result = await ListStorageEntries.request({
140
+ namespace,
141
+ prefix: prefix ?? ROOT_PATH,
142
+ limit: DEFAULT_FETCH_LIMIT,
143
+ ...(pageToken != null ? { pageToken } : {}),
144
+ });
145
+ if (result.error) {
146
+ throw new Error(result.error);
147
+ }
148
+ setEntries({
149
+ namespace,
150
+ prefix,
151
+ entries: result.entries,
152
+ nextPageToken: result.next_page_token,
153
+ append,
154
+ });
155
+ return result;
156
+ }
157
+
96
158
  /**
97
159
  * Hook that fetches and caches storage entries for a given namespace/prefix.
98
160
  * Entries are fetched on first access and cached in the store for subsequent renders.
99
161
  */
100
162
  export function useStorageEntries(namespace: string, prefix?: string) {
101
- const { entriesByPath } = useStorage();
163
+ const { entriesByPath, pageMetadataByPath } = useStorage();
102
164
  const { setEntries } = useStorageActions();
103
- const cached = entriesByPath.get(storagePathKey(namespace, prefix));
165
+ const key = storagePathKey(namespace, prefix);
166
+ const cached = entriesByPath.get(key);
167
+ const metadata = pageMetadataByPath.get(key);
168
+ const nextPageToken = metadata?.nextPageToken ?? null;
169
+ const isLoadingMoreRef = useRef(false);
170
+ const [isLoadingMore, setIsLoadingMore] = useState(false);
171
+ const [loadMoreError, setLoadMoreError] = useState<Error | undefined>();
104
172
 
105
173
  const { isPending, error, refetch } = useAsyncData(async () => {
106
174
  if (cached) {
107
175
  return;
108
176
  }
109
- const result = await ListStorageEntries.request({
177
+ await fetchStorageEntriesPage({
110
178
  namespace,
111
- prefix: prefix ?? ROOT_PATH,
112
- limit: DEFAULT_FETCH_LIMIT,
179
+ prefix,
180
+ setEntries,
113
181
  });
114
- if (result.error) {
115
- throw new Error(result.error);
116
- }
117
- setEntries({ namespace, prefix, entries: result.entries });
118
182
  }, [namespace, prefix, cached === undefined]);
119
183
 
184
+ const loadMore = useCallback(async () => {
185
+ if (nextPageToken == null || isLoadingMoreRef.current) {
186
+ return;
187
+ }
188
+
189
+ isLoadingMoreRef.current = true;
190
+ setIsLoadingMore(true);
191
+ setLoadMoreError(undefined);
192
+ try {
193
+ await fetchStorageEntriesPage({
194
+ namespace,
195
+ prefix,
196
+ pageToken: nextPageToken,
197
+ append: true,
198
+ setEntries,
199
+ });
200
+ } catch (error) {
201
+ setLoadMoreError(
202
+ error instanceof Error ? error : new Error(String(error)),
203
+ );
204
+ } finally {
205
+ isLoadingMoreRef.current = false;
206
+ setIsLoadingMore(false);
207
+ }
208
+ }, [namespace, prefix, nextPageToken, setEntries]);
209
+
120
210
  return {
121
211
  entries: cached ?? [],
122
212
  isPending: isPending && !cached,
123
213
  error: cached ? undefined : error,
214
+ hasMore: nextPageToken !== null,
215
+ loadMore,
216
+ isLoadingMore,
217
+ loadMoreError,
124
218
  refetch,
125
219
  };
126
220
  }
127
221
 
222
+ export function useStoragePageFetcher() {
223
+ const { setEntries } = useStorageActions();
224
+ return useCallback(
225
+ (opts: {
226
+ namespace: string;
227
+ prefix: string | null | undefined;
228
+ pageToken?: string | null;
229
+ append?: boolean;
230
+ }) =>
231
+ fetchStorageEntriesPage({
232
+ ...opts,
233
+ setEntries,
234
+ }),
235
+ [setEntries],
236
+ );
237
+ }
238
+
128
239
  export const exportedForTesting = {
129
240
  reducer,
130
241
  createActions,
@@ -30,6 +30,12 @@ export interface StorageState {
30
30
  namespaces: StorageNamespace[];
31
31
  /** Lazy-loaded entries keyed by "namespace::prefix" */
32
32
  entriesByPath: ReadonlyMap<StoragePathKey, StorageEntry[]>;
33
+ /** Pagination metadata keyed by "namespace::prefix" */
34
+ pageMetadataByPath: ReadonlyMap<StoragePathKey, StoragePageMetadata>;
35
+ }
36
+
37
+ export interface StoragePageMetadata {
38
+ nextPageToken: string | null;
33
39
  }
34
40
 
35
41
  export function storageUrl(
@@ -1,26 +0,0 @@
1
- import{s as qe}from"./chunk-LvLJmgfZ.js";import{i as Rt,l as ke,n as ee,p as Ue,u as ye}from"./useEvent-D91BmmQi.js";import{t as Vt}from"./react-Bj1aDYRI.js";import{D as At,Fn as We,Oi as Ke,wi as Et,wr as Bt}from"./cells-k7Js5h2t.js";import"./react-dom-CSu739Rf.js";import{t as fe}from"./compiler-runtime-B3qBwwSJ.js";import{_ as De}from"./useEventListener-DvoEXWke.js";import{t as Ht}from"./invariant-BUdrueMv.js";import{f as Ge,h as Lt}from"./utils-CvI-39U6.js";import{T as Fe}from"./config-ClMcu_sV.js";import{t as ie}from"./cn-DCUzRj2J.js";import{t as qt}from"./jsx-runtime-BqBOg78p.js";import"./fullscreen-DFky0PAA.js";import{n as Ut}from"./multi-map-C4OANz8X.js";import{o as Wt}from"./alert-dialog-5BGIfskO.js";import"./popover-CNCYAwbC.js";import{a as V,c as ue,p as Kt,r as Gt,t as Jt}from"./dropdown-menu-CZ4XbE-c.js";import{Nt as Me,a as Yt,i as Je,m as Zt,o as _e}from"./JsonOutput-DXzjDImT.js";import{c as Qt,i as Pe,r as Ce}from"./download-BS31LU22.js";import{r as Ye}from"./radio-group-DS_mmqHJ.js";import{t as A}from"./tooltip-B_PkSKN3.js";import{n as Xt,t as R}from"./button-BbCh-29a.js";import{wt as ea}from"./dist-D0HyMpgV.js";import"./cjs-BRGiG41H.js";import"./main-B0OX4z33.js";import"./useNonce-DfoVjkkH.js";import{n as ta,r as ze}from"./requests-DIwGYs0l.js";import{t as re}from"./createLucideIcon-D5guW7EU.js";import{a as Ze,c as Qe,i as Xe,n as Se,o as Te,r as aa,t as na}from"./state-DTislnZA.js";import{n as ra}from"./LazyAnyLanguageCodeMirror-C7ALwTI_.js";import{t as sa}from"./x-C-6liIBr.js";import{a as la,i as $e,n as oa,r as et,t as je}from"./tree-actions-XvgFV23w.js";import{n as Oe}from"./markdown-renderer-BwjWZESf.js";import{u as ia}from"./toDate-B5A0DFEz.js";import{t as tt}from"./copy-BwrPA9zQ.js";import{t as Ie}from"./external-link-BTNxSavU.js";import{a as ca,i as at,n as nt,r as da,t as ma}from"./file-icons-on-PIYta.js";import{t as rt}from"./file-BrdxGLRX.js";import{i as st,r as pa,t as lt}from"./add-connection-dialog-CTTPp4DA.js";import{n as Re,t as ha}from"./spinner-Bhir8k53.js";import{a as xa,c as fa,d as ua,f as ya,i as ja,l as ga,n as ba,r as va,t as wa,u as Na}from"./file-name-input-D-E8LtaP.js";import{t as ot}from"./plus-BgB18UzY.js";import{t as it}from"./refresh-cw-DHwG4Mac.js";import{t as ka}from"./save-Clg5dMoP.js";import{t as Fa}from"./triangle-alert-D2p96PEF.js";import{n as _a,t as Ca}from"./es-By9LYOsD.js";import"./dist-HyCgERnW.js";import"./dist-BwnT-_gD.js";import"./dist-rBRbke5D.js";import"./dist-RMRSa-Mj.js";import"./dist-BURue7-e.js";import{t as te}from"./use-toast-CJ1Tj2eC.js";import{t as Sa}from"./paths-D5zczhUD.js";import"./session-0B5NBztP.js";import"./purify.es-B9KxLTTS.js";import"./dates-CTxr0EqQ.js";import{n as ge}from"./copy-LK56fFow.js";import{t as Da}from"./copy-icon-BuRdHNPA.js";import{t as ct}from"./context-QkTujrKn.js";import{n as dt}from"./ImperativeModal-BW1dmntO.js";import{t as mt}from"./blob-Bgnx1kuY.js";import"./utils-DCL4n9wx.js";import"./vega-loader.browser-C8wT63Va.js";import"./defaultLocale-BLUna9fQ.js";import"./defaultLocale-DzliDDTm.js";import{n as Ma,t as Pa}from"./alert-yTS3WpF4.js";import{n as pt}from"./error-banner-D0xvrLog.js";import"./chunk-5FQGJX7Z-Bp9g5nD2.js";import"./html-to-image-rLeQGF-G.js";import{o as za}from"./focus-CRI5ilWC.js";import{n as Ve}from"./useAsyncData-bgszE9F0.js";import"./react-resizable-panels.browser.esm-CV8-hvjx.js";import{a as Ta,f as $a,o as ht,t as Oa}from"./command-BmOGG6-2.js";import{a as Ia}from"./renderShortcut--ku7VECI.js";import{t as Ra}from"./bundle.esm-DjhGJy4I.js";import{n as Va}from"./pathUtils-DPJ-EgtH.js";import{n as Aa}from"./semaphore-qUGKVeAE.js";import{t as Ea}from"./empty-state-vCWg-_A9.js";import{t as Ae}from"./formatting-DuH2AQgo.js";import{a as Ba,i as Ha,n as xt,r as ft,t as ut}from"./components-CXG-2UWv.js";import{n as yt,t as La}from"./marimo-icons-CLbC-oB3.js";import{t as qa}from"./links-DoPgJNku.js";var Ua=re("book-plus",[["path",{d:"M12 7v6",key:"lw1j43"}],["path",{d:"M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H19a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6.5a1 1 0 0 1 0-5H20",key:"k3hazp"}],["path",{d:"M9 10h6",key:"9gxzsh"}]]),Wa=re("copy-minus",[["line",{x1:"12",x2:"18",y1:"15",y2:"15",key:"1nscbv"}],["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]]),jt=re("file-plus-corner",[["path",{d:"M11.35 22H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.706.706l3.588 3.588A2.4 2.4 0 0 1 20 8v5.35",key:"17jvcc"}],["path",{d:"M14 2v5a1 1 0 0 0 1 1h5",key:"wfsgrz"}],["path",{d:"M14 19h6",key:"bvotb8"}],["path",{d:"M17 16v6",key:"18yu1i"}]]),Ka=re("file-symlink",[["path",{d:"M4 11V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.706.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h7",key:"huwfnr"}],["path",{d:"M14 2v5a1 1 0 0 0 1 1h5",key:"wfsgrz"}],["path",{d:"m10 18 3-3-3-3",key:"18f6ys"}]]),gt=re("folder-plus",[["path",{d:"M12 10v6",key:"1bos4e"}],["path",{d:"M9 13h6",key:"1uhe8q"}],["path",{d:"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z",key:"1kt360"}]]),bt=re("list-tree",[["path",{d:"M8 5h13",key:"1pao27"}],["path",{d:"M13 12h8",key:"h98zly"}],["path",{d:"M13 19h8",key:"c3s6r1"}],["path",{d:"M3 10a2 2 0 0 0 2 2h3",key:"1npucw"}],["path",{d:"M3 5v12a2 2 0 0 0 2 2h3",key:"x1gjn2"}]]),Ga=re("square-play",[["rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",key:"h1oib"}],["path",{d:"M9 9.003a1 1 0 0 1 1.517-.859l4.997 2.997a1 1 0 0 1 0 1.718l-4.997 2.997A1 1 0 0 1 9 14.996z",key:"kmsa83"}]]),vt=re("view",[["path",{d:"M21 17v2a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-2",key:"mrq65r"}],["path",{d:"M21 7V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v2",key:"be3xqs"}],["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["path",{d:"M18.944 12.33a1 1 0 0 0 0-.66 7.5 7.5 0 0 0-13.888 0 1 1 0 0 0 0 .66 7.5 7.5 0 0 0 13.888 0",key:"11ak4c"}]]),$=qe(Vt(),1),Ja=fe(),a=qe(qt(),1);const wt=t=>{let e=(0,Ja.c)(17),{filename:n,filenameIcon:o,onBack:i,onRefresh:r,onDownload:m,actions:c}=t,x;e[0]===i?x=e[1]:(x=i&&(0,a.jsx)(A,{content:"Back to file list",children:(0,a.jsx)(R,{variant:"text",size:"xs",onClick:i,children:(0,a.jsx)(Qe,{className:"h-4 w-4"})})}),e[0]=i,e[1]=x);let s;e[2]!==n||e[3]!==o?(s=n?(0,a.jsxs)("span",{className:"flex items-center gap-1.5 flex-1 min-w-0 text-xs font-semibold truncate",children:[o,n]}):(0,a.jsx)("span",{className:"flex-1"}),e[2]=n,e[3]=o,e[4]=s):s=e[4];let f;e[5]===r?f=e[6]:(f=r&&(0,a.jsx)(A,{content:"Refresh",children:(0,a.jsx)(R,{variant:"text",size:"xs",onClick:r,children:(0,a.jsx)(it,{className:"h-3.5 w-3.5"})})}),e[5]=r,e[6]=f);let h;e[7]===m?h=e[8]:(h=m&&(0,a.jsx)(A,{content:"Download",children:(0,a.jsx)(R,{variant:"text",size:"xs",onClick:m,children:(0,a.jsx)(Me,{className:"h-3.5 w-3.5"})})}),e[7]=m,e[8]=h);let p;e[9]!==c||e[10]!==f||e[11]!==h?(p=(0,a.jsxs)("div",{className:"flex items-center gap-0.5 shrink-0",children:[f,c,h]}),e[9]=c,e[10]=f,e[11]=h,e[12]=p):p=e[12];let g;return e[13]!==x||e[14]!==s||e[15]!==p?(g=(0,a.jsxs)("div",{className:"flex items-center shrink-0 border-b px-1 gap-1",children:[x,s,p]}),e[13]=x,e[14]=s,e[15]=p,e[16]=g):g=e[16],g};var Ya=new Set(["http","file","in-memory"]);function Ee(t){return JSON.stringify(t).slice(1,-1)}const Nt=[{id:"read-file",label:"Insert read snippet",icon:Ua,getCode:t=>{if(t.entry.kind==="directory")return null;let e=Ee(t.entry.path);return t.backendType==="obstore"?`_data = ${t.variableName}.get("${e}").bytes()
2
- _data`:`_data = ${t.variableName}.cat_file("${e}")
3
- _data`}},{id:"download-file",label:"Insert download snippet",icon:Ka,getCode:t=>{if(t.entry.kind==="directory")return null;let e=Ee(t.entry.path);if(t.backendType==="obstore")return Ya.has(t.protocol)?null:`from datetime import timedelta
4
- from obstore import sign
5
-
6
- signed_url = sign(
7
- ${t.variableName}, "GET", "${e}",
8
- expires_in=timedelta(hours=1),
9
- )
10
- signed_url`;let n=Ee(t.entry.path.split("/").pop()||"download");return`${t.variableName}.get("${e}", "${n}")`}}];var Za=100*1024*1024;function Qa(t){let e=t.endsWith("/")?t.slice(0,-1):t,n=e.split("/");return n[n.length-1]||e}const Xa=({entry:t,namespace:e,protocol:n,backendType:o,onBack:i})=>{let{locale:r}=ct(),m=Ye(),c=Qa(t.path),x=t.mimeType||"text/plain",s=_e(x),f=s&&t.size>Za&&t.size>0,{data:h,isPending:p,error:g,refetch:y}=Ve(async()=>{if(f)return null;let d=await Te.request({namespace:e,path:t.path,preview:!s});if(d.error)throw Error(d.error);if(!d.url)throw Error("No URL returned");if(s)return{type:"media",url:d.url};let b=await fetch(d.url);if(!b.ok)throw Error(`Failed to fetch preview: ${b.statusText}`);return{type:"text",content:await b.text()}},[e,t.path,s,f]),w=(0,$.useCallback)(async()=>{try{let d=await Te.request({namespace:e,path:t.path});if(d.error){te({title:"Download failed",description:d.error,variant:"danger"});return}d.url&&Pe(d.url,d.filename??c)}catch(d){De.error("Failed to download storage entry",d),te({title:"Download failed",description:String(d),variant:"danger"})}},[e,t.path,c]),v=Nt.map(d=>{let b=d.getCode({variableName:e,protocol:n,entry:t,backendType:o});if(b===null)return null;let N=d.icon;return(0,a.jsx)(A,{content:d.label,children:(0,a.jsx)(R,{variant:"text",size:"xs",onClick:()=>m(b),"aria-label":d.label,children:(0,a.jsx)(N,{className:"h-3.5 w-3.5"})})},d.id)}),l=(0,a.jsx)(wt,{filename:c,filenameIcon:at(c),onBack:i,onDownload:w,actions:v}),j=({includeMime:d=!1})=>(0,a.jsxs)("div",{className:"grid grid-cols-[auto_1fr] gap-x-4 gap-y-1.5 p-4 text-xs",children:[(0,a.jsx)("span",{className:"text-muted-foreground font-medium",children:"Path"}),(0,a.jsxs)("div",{className:"truncate flex items-center gap-1.5",children:[(0,a.jsx)("span",{className:"font-mono text-[11px]",children:t.path}),(0,a.jsx)(Da,{value:t.path,className:"h-3 w-3"})]}),d&&(0,a.jsx)("span",{className:"text-muted-foreground font-medium",children:"Type"}),d&&(0,a.jsx)("span",{children:x}),t.size>0&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("span",{className:"text-muted-foreground font-medium",children:"Size"}),(0,a.jsx)("span",{children:Ae(t.size,r)})]}),t.lastModified!=null&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("span",{className:"text-muted-foreground font-medium",children:"Modified"}),(0,a.jsx)("span",{children:new Date(t.lastModified*1e3).toLocaleString()})]})]});return f?(0,a.jsxs)("div",{className:"flex flex-col h-full",children:[l,j({includeMime:!0}),(0,a.jsxs)("div",{className:"px-4 pb-4 text-xs text-muted-foreground italic",children:["File is too large to preview (",Ae(t.size,r),")."]})]}):p?(0,a.jsxs)("div",{className:"flex flex-col h-full",children:[l,j({}),(0,a.jsxs)("div",{className:"flex-1 flex items-center justify-center gap-2 text-xs text-muted-foreground min-h-24",children:[(0,a.jsx)(Re,{className:"h-4 w-4 animate-spin"}),"Loading preview..."]})]}):g?(0,a.jsxs)("div",{className:"flex flex-col h-full",children:[l,j({includeMime:!0}),(0,a.jsxs)("div",{className:"px-4 pb-4 text-xs text-destructive",children:["Failed to load preview: ",g.message]}),(0,a.jsx)("div",{className:"px-4 pb-4",children:(0,a.jsxs)(R,{variant:"secondary",size:"xs",onClick:y,children:[(0,a.jsx)(it,{className:"h-3 w-3 mr-1"}),"Retry"]})})]}):h?(0,a.jsxs)("div",{className:"flex flex-col h-full",children:[l,j({}),(0,a.jsx)(Je,{mimeType:x,contents:h.type==="text"?h.content:void 0,mediaSource:h.type==="media"?{url:h.url}:void 0})]}):(0,a.jsxs)("div",{className:"flex flex-col h-full",children:[l,j({includeMime:!0}),(0,a.jsxs)("div",{className:"p-4 flex items-center gap-2 text-xs text-muted-foreground",children:[(0,a.jsx)(rt,{className:"h-4 w-4"}),"Preview not available for this file type."]})]})};var Be=fe(),en=16;function se(t){return{paddingLeft:t*en}}function tn(t,e){return new Date(t*1e3).toLocaleDateString(e,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}function kt(t){let e=t.endsWith("/")?t.slice(0,-1):t,n=e.split("/");return n[n.length-1]||e}function Ft(t,e){var o;let n=(o=t.metadata)==null?void 0:o.id;return typeof n=="string"&&n.length>0?n:`${t.path}::${e}`}function He(t,{namespace:e,searchValue:n,entriesByPath:o}){let i=n.toLowerCase();if(kt(t.path).toLowerCase().includes(i))return!0;if(t.kind==="directory"){let r=o.get(Ze(e,t.path));if(r)return r.some(m=>He(m,{namespace:e,searchValue:n,entriesByPath:o}))}return!1}function _t(t,e){return e.searchValue.trim()?t.filter(n=>He(n,e)):t}var an=t=>{let e=(0,Be.c)(37),{namespace:n,protocol:o,rootPath:i,backendType:r,prefix:m,depth:c,locale:x,searchValue:s,onOpenFile:f}=t,{entriesByPath:h}=Se(),{entries:p,isPending:g,error:y}=Xe(n,m);if(g){let l;e[0]===c?l=e[1]:(l=se(c),e[0]=c,e[1]=l);let j;e[2]===Symbol.for("react.memo_cache_sentinel")?(j=(0,a.jsx)(Re,{className:"h-3 w-3 animate-spin"}),e[2]=j):j=e[2];let d;return e[3]===l?d=e[4]:(d=(0,a.jsxs)("div",{className:"flex items-center gap-1.5 py-1 text-xs text-muted-foreground",style:l,children:[j,"Loading..."]}),e[3]=l,e[4]=d),d}if(y){let l;e[5]===c?l=e[6]:(l=se(c),e[5]=c,e[6]=l);let j;return e[7]!==y.message||e[8]!==l?(j=(0,a.jsxs)("div",{className:"py-1 text-xs text-destructive",style:l,children:["Failed to load: ",y.message]}),e[7]=y.message,e[8]=l,e[9]=j):j=e[9],j}if(p.length===0){let l;e[10]===c?l=e[11]:(l=se(c),e[10]=c,e[11]=l);let j;return e[12]===l?j=e[13]:(j=(0,a.jsx)("div",{className:"py-1 text-xs text-muted-foreground italic",style:l,children:"Empty"}),e[12]=l,e[13]=j),j}let w;if(e[14]!==r||e[15]!==p||e[16]!==c||e[17]!==h||e[18]!==x||e[19]!==n||e[20]!==f||e[21]!==o||e[22]!==i||e[23]!==s){let l=_t(p,{namespace:n,searchValue:s,entriesByPath:h}),j;e[25]!==r||e[26]!==p||e[27]!==c||e[28]!==x||e[29]!==n||e[30]!==f||e[31]!==o||e[32]!==i||e[33]!==s?(j=d=>{let b=Ft(d,p.indexOf(d));return(0,a.jsx)(Ct,{rowKey:b,entry:d,namespace:n,protocol:o,rootPath:i,backendType:r,depth:c,locale:x,searchValue:s,onOpenFile:f},b)},e[25]=r,e[26]=p,e[27]=c,e[28]=x,e[29]=n,e[30]=f,e[31]=o,e[32]=i,e[33]=s,e[34]=j):j=e[34],w=l.map(j),e[14]=r,e[15]=p,e[16]=c,e[17]=h,e[18]=x,e[19]=n,e[20]=f,e[21]=o,e[22]=i,e[23]=s,e[24]=w}else w=e[24];let v;return e[35]===w?v=e[36]:(v=(0,a.jsx)(a.Fragment,{children:w}),e[35]=w,e[36]=v),v},Ct=({entry:t,rowKey:e,namespace:n,protocol:o,rootPath:i,backendType:r,depth:m,locale:c,searchValue:x,onOpenFile:s})=>{var N;let[f,h]=(0,$.useState)(!1),{entriesByPath:p}=Se(),g=Ye(),y=t.kind==="directory",w=kt(t.path),v=!!x.trim(),l=y&&v&&w.toLowerCase().includes(x.trim().toLowerCase()),j=y&&v&&!!((N=p.get(Ze(n,t.path)))!=null&&N.some(u=>He(u,{namespace:n,searchValue:x,entriesByPath:p}))),d=f||j,b=(0,$.useCallback)(async()=>{try{let u=await Te.request({namespace:n,path:t.path});if(u.error){te({title:"Download failed",description:u.error,variant:"danger"});return}u.url&&Pe(u.url,u.filename??"download")}catch(u){De.error("Failed to download storage entry",u),te({title:"Download failed",description:String(u),variant:"danger"})}},[n,t.path]);return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(ht,{className:ie("text-xs flex items-center gap-1.5 cursor-pointer rounded-none group h-6.5",y&&"font-medium"),style:se(m),value:`${n}:${e}`,onSelect:()=>{y?h(!d):s({entry:t,namespace:n,protocol:o,backendType:r})},children:[y?(0,a.jsx)($e,{isExpanded:d,className:"h-3 w-3"}):(0,a.jsx)("span",{className:"w-3 shrink-0"}),y?(0,a.jsx)(ca,{className:ie("h-3.5 w-3.5 shrink-0",nt.directory)}):at(w),(0,a.jsx)("span",{className:"truncate flex-1 text-left",children:w}),(0,a.jsxs)("div",{className:"flex items-center",children:[t.size>0&&(0,a.jsx)("span",{className:"text-[10px] text-muted-foreground pr-2 opacity-0 group-hover:opacity-100 transition-opacity tabular-nums",children:Ae(t.size,c)}),t.lastModified!=null&&(0,a.jsx)(A,{content:`Last modified: ${new Date(t.lastModified*1e3).toLocaleString()}`,children:(0,a.jsx)("span",{className:"text-[10px] text-muted-foreground pr-1 opacity-0 group-hover:opacity-100 transition-opacity whitespace-nowrap",children:tn(t.lastModified,c)})}),(0,a.jsxs)(Jt,{children:[(0,a.jsx)(Kt,{asChild:!0,children:(0,a.jsx)(oa,{iconClassName:"h-3 w-3",onClick:u=>u.stopPropagation()})}),(0,a.jsxs)(Gt,{align:"end",onClick:u=>u.stopPropagation(),onCloseAutoFocus:u=>u.preventDefault(),children:[!y&&(0,a.jsxs)(V,{onSelect:()=>s({entry:t,namespace:n,protocol:o,backendType:r}),children:[(0,a.jsx)(vt,{className:"h-3.5 w-3.5 mr-2"}),"View"]}),(0,a.jsxs)(V,{onSelect:async()=>{await ge(t.path),te({title:"Copied to clipboard"})},children:[(0,a.jsx)(tt,{className:je}),"Copy path"]}),!y&&(0,a.jsxs)(V,{onSelect:()=>b(),children:[(0,a.jsx)(Me,{className:"h-3.5 w-3.5 mr-2"}),"Download"]}),(0,a.jsx)(ue,{}),Nt.map(u=>{let F=u.getCode({variableName:n,protocol:o,entry:t,backendType:r});if(F===null)return null;let _=u.icon;return(0,a.jsxs)(V,{onSelect:()=>g(F),children:[(0,a.jsx)(_,{className:je}),u.label]},u.id)})]})]})]})]}),y&&d&&(0,a.jsx)(an,{namespace:n,protocol:o,rootPath:i,backendType:r,prefix:t.path,depth:m+1,locale:c,searchValue:l?"":x,onOpenFile:s})]})},nn=t=>{let e=(0,Be.c)(43),{namespace:n,locale:o,searchValue:i,onOpenFile:r}=t,[m,c]=(0,$.useState)(!0),{entriesByPath:x}=Se(),{clearNamespaceCache:s}=aa(),f=n.name??n.displayName,{entries:h,isPending:p,error:g,refetch:y}=Xe(f),w;e[0]!==s||e[1]!==f||e[2]!==y?(w=d=>{d.stopPropagation(),s(f),y()},e[0]=s,e[1]=f,e[2]=y,e[3]=w):w=e[3];let v=w,l=p?n.storageEntries:h,j;if(e[4]!==l||e[5]!==x||e[6]!==g||e[7]!==v||e[8]!==m||e[9]!==p||e[10]!==o||e[11]!==n.backendType||e[12]!==n.displayName||e[13]!==n.name||e[14]!==n.protocol||e[15]!==n.rootPath||e[16]!==f||e[17]!==r||e[18]!==i){let d=_t(l,{namespace:f,searchValue:i,entriesByPath:x}),b;e[20]===m?b=e[21]:(b=()=>c(!m),e[20]=m,e[21]=b);let N;e[22]===m?N=e[23]:(N=(0,a.jsx)($e,{isExpanded:m,className:"h-3 w-3"}),e[22]=m,e[23]=N);let u;e[24]===n.protocol?u=e[25]:(u=(0,a.jsx)(pa,{protocol:n.protocol}),e[24]=n.protocol,e[25]=u);let F;e[26]===n.displayName?F=e[27]:(F=(0,a.jsx)("span",{children:n.displayName}),e[26]=n.displayName,e[27]=F);let _;e[28]===n.name?_=e[29]:(_=n.name&&(0,a.jsxs)("span",{className:"text-xs text-muted-foreground font-normal",children:["(",(0,a.jsx)(Ba,{variableName:n.name}),")"]}),e[28]=n.name,e[29]=_);let C;e[30]===v?C=e[31]:(C=(0,a.jsx)(et,{onClick:v,tooltip:"Refresh storage connection",className:"p-0",iconClassName:"h-3 w-3"}),e[30]=v,e[31]=C);let P=n.rootPath||"(root)",S;e[32]===P?S=e[33]:(S=(0,a.jsx)("span",{className:"text-[10px] text-muted-foreground font-normal tabular-nums ml-auto",children:P}),e[32]=P,e[33]=S);let D;e[34]!==n.name||e[35]!==S||e[36]!==b||e[37]!==N||e[38]!==u||e[39]!==F||e[40]!==_||e[41]!==C?(D=(0,a.jsxs)(ht,{value:n.name,onSelect:b,className:"flex flex-row font-semibold h-7 text-xs gap-1.5 bg-(--slate-2) text-muted-foreground rounded-none",children:[N,u,F,_,C,S]}),e[34]=n.name,e[35]=S,e[36]=b,e[37]=N,e[38]=u,e[39]=F,e[40]=_,e[41]=C,e[42]=D):D=e[42],j=(0,a.jsxs)(a.Fragment,{children:[D,m&&(0,a.jsxs)(a.Fragment,{children:[p&&l.length===0&&(0,a.jsxs)("div",{className:"flex items-center gap-1.5 py-1 text-xs text-muted-foreground",style:se(1),children:[(0,a.jsx)(Re,{className:"h-3 w-3 animate-spin"}),"Loading..."]}),g&&l.length===0&&(0,a.jsx)(Zt,{error:g,style:se(1),className:"py-1 text-xs h-auto overflow-auto max-h-32 items-start",showIcon:!1}),!p&&l.length===0&&!g&&(0,a.jsx)("div",{className:"py-1 text-xs text-muted-foreground italic",style:se(1),children:"No entries"}),i&&d.length===0&&l.length>0&&(0,a.jsx)("div",{className:"py-1 text-xs text-muted-foreground italic",style:se(1),children:"No matches"}),d.map(I=>{let T=Ft(I,l.indexOf(I));return(0,a.jsx)(Ct,{rowKey:T,entry:I,namespace:f,protocol:n.protocol,rootPath:n.rootPath,backendType:n.backendType,depth:1,locale:o,searchValue:i,onOpenFile:r},T)})]})]}),e[4]=l,e[5]=x,e[6]=g,e[7]=v,e[8]=m,e[9]=p,e[10]=o,e[11]=n.backendType,e[12]=n.displayName,e[13]=n.name,e[14]=n.protocol,e[15]=n.rootPath,e[16]=f,e[17]=r,e[18]=i,e[19]=j}else j=e[19];return j};const rn=()=>{let t=(0,Be.c)(31),{namespaces:e}=Se(),{locale:n}=ct(),[o,i]=(0,$.useState)(""),[r,m]=(0,$.useState)(null),c=!!o.trim();if(e.length===0){let b;t[0]===Symbol.for("react.memo_cache_sentinel")?(b=(0,a.jsxs)("span",{children:["Create an obstore or fsspec connection in your notebook. See the"," ",(0,a.jsx)("a",{className:"text-link",href:"https://docs.marimo.io/guides/working_with_data/remote_storage/#quick-start",target:"_blank",rel:"noopener noreferrer",children:"docs"}),"."]}),t[0]=b):b=t[0];let N;return t[1]===Symbol.for("react.memo_cache_sentinel")?(N=(0,a.jsx)(Ea,{title:"No storage connected",description:b,action:(0,a.jsx)(lt,{defaultTab:"storage",children:(0,a.jsxs)(R,{variant:"outline",size:"sm",children:["Add remote storage",(0,a.jsx)(ot,{className:"h-4 w-4 ml-2"})]})}),icon:(0,a.jsx)(st,{className:"h-8 w-8"})}),t[1]=N):N=t[1],N}let x;t[2]===r?x=t[3]:(x=r&&(0,a.jsx)(Xa,{entry:r.entry,namespace:r.namespace,protocol:r.protocol,backendType:r.backendType,onBack:()=>m(null)}),t[2]=r,t[3]=x);let s=r&&"hidden",f;t[4]===s?f=t[5]:(f=ie("border-b bg-background rounded-none h-full pb-10 overflow-auto outline-hidden scrollbar-thin",s),t[4]=s,t[5]=f);let h;t[6]===o?h=t[7]:(h=(0,a.jsx)(Ta,{placeholder:"Search entries...",className:"h-6 m-1",value:o,onValueChange:i,rootClassName:"flex-1 border-b-0"}),t[6]=o,t[7]=h);let p;t[8]===c?p=t[9]:(p=c&&(0,a.jsx)(R,{variant:"text",size:"xs",className:"float-right border-none px-2 m-0 h-full",onClick:()=>i(""),children:(0,a.jsx)(sa,{className:"h-4 w-4"})}),t[8]=c,t[9]=p);let g;t[10]===Symbol.for("react.memo_cache_sentinel")?(g=(0,a.jsx)(A,{content:"Filters loaded entries only. Expand directories to include their contents in the search.",delayDuration:200,children:(0,a.jsx)(ia,{className:"h-3.5 w-3.5 shrink-0 cursor-help text-muted-foreground hover:text-foreground mr-2"})}),t[10]=g):g=t[10];let y;t[11]===Symbol.for("react.memo_cache_sentinel")?(y=(0,a.jsx)(lt,{defaultTab:"storage",children:(0,a.jsx)(R,{variant:"ghost",size:"sm",className:"px-2 border-0 border-l border-muted-background rounded-none focus-visible:ring-0 focus-visible:ring-offset-0",children:(0,a.jsx)(ot,{className:"h-4 w-4"})})}),t[11]=y):y=t[11];let w;t[12]!==h||t[13]!==p?(w=(0,a.jsxs)("div",{className:"flex items-center w-full border-b",children:[h,p,g,y]}),t[12]=h,t[13]=p,t[14]=w):w=t[14];let v;if(t[15]!==n||t[16]!==e||t[17]!==o){let b;t[19]!==n||t[20]!==o?(b=N=>(0,a.jsx)(nn,{namespace:N,locale:n,searchValue:o,onOpenFile:m},N.name??N.displayName),t[19]=n,t[20]=o,t[21]=b):b=t[21],v=e.map(b),t[15]=n,t[16]=e,t[17]=o,t[18]=v}else v=t[18];let l;t[22]===v?l=t[23]:(l=(0,a.jsx)($a,{className:"flex flex-col",children:v}),t[22]=v,t[23]=l);let j;t[24]!==f||t[25]!==w||t[26]!==l?(j=(0,a.jsxs)(Oa,{className:f,shouldFilter:!1,children:[w,l]}),t[24]=f,t[25]=w,t[26]=l,t[27]=j):j=t[27];let d;return t[28]!==x||t[29]!==j?(d=(0,a.jsxs)("div",{className:"h-full flex flex-col",children:[x,j]}),t[28]=x,t[29]=j,t[30]=d):d=t[30],d};var St=fe(),Dt=(0,$.createContext)(null);function sn(){return(0,$.useContext)(Dt)??void 0}var ln=t=>{let e=(0,St.c)(3),{children:n}=t,o=ua(),i;return e[0]!==n||e[1]!==o?(i=(0,a.jsx)(Dt.Provider,{value:o,children:n}),e[0]=n,e[1]=o,e[2]=i):i=e[2],i};const on=t=>{let e=(0,St.c)(5),{children:n}=t,[o,i]=(0,$.useState)(null),r;e[0]!==n||e[1]!==o?(r=o&&(0,a.jsx)(ya,{backend:Na,options:{rootElement:o},children:(0,a.jsx)(ln,{children:n})}),e[0]=n,e[1]=o,e[2]=r):r=e[2];let m;return e[3]===r?m=e[4]:(m=(0,a.jsx)("div",{ref:i,className:"contents",children:r}),e[3]=r,e[4]=m),m};var Le=new Map;const cn=({file:t,onOpenNotebook:e})=>{let{sendFileDetails:n,sendUpdateFile:o}=ze(),i=ye(Lt),r=ye(Ge),m=ye(Et),[c,x]=(0,$.useState)(""),{data:s,isPending:f,error:h,setData:p,refetch:g}=Ve(async()=>{let u=await n({path:t.path}),F=u.contents||"";return x(Le.get(t.path)||F),u},[t.path]),y=async()=>{c!==(s==null?void 0:s.contents)&&await o({path:t.path,contents:c}).then(u=>{u.success&&(p(F=>({...F,contents:c})),x(c))})},w=(0,$.useRef)(c);if(w.current=c,(0,$.useEffect)(()=>()=>{if(!(s!=null&&s.contents))return;let u=w.current;u===s.contents?Le.delete(t.path):Le.set(t.path,u)},[t.path,s==null?void 0:s.contents]),h)return(0,a.jsx)(pt,{error:h});if(f||!s)return null;let v=s.mimeType||"text/plain",l=v in Yt,j=m&&s.file.isMarimoFile&&(t.path===m||t.path.endsWith(`/${m}`));if(!s.contents&&!l)return(0,a.jsxs)("div",{className:"grid grid-cols-2 gap-2 p-6",children:[(0,a.jsx)("div",{className:"font-bold text-muted-foreground",children:"Name"}),(0,a.jsx)("div",{children:s.file.name}),(0,a.jsx)("div",{className:"font-bold text-muted-foreground",children:"Type"}),(0,a.jsx)("div",{children:v})]});let d=(0,a.jsx)(wt,{filename:s.file.name,onRefresh:g,onDownload:r?void 0:()=>{if(s.isBase64&&s.contents){_e(v)?Pe(Oe(s.contents,v),s.file.name):Ce(mt(Oe(s.contents,s.mimeType||"application/octet-stream")),s.file.name);return}Ce(new Blob([s.contents||c],{type:v}),s.file.name)},actions:(0,a.jsxs)(a.Fragment,{children:[t.isMarimoFile&&!Fe()&&(0,a.jsx)(A,{content:"Open notebook",children:(0,a.jsx)(R,{variant:"text",size:"xs",onClick:u=>e(u),children:(0,a.jsx)(Ie,{className:"h-3.5 w-3.5"})})}),!_e(v)&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(A,{content:"Copy contents to clipboard",children:(0,a.jsx)(R,{variant:"text",size:"xs",onClick:async()=>{await ge(c)},children:(0,a.jsx)(tt,{className:"h-3.5 w-3.5"})})}),(0,a.jsx)(A,{content:Ia("global.save"),children:(0,a.jsx)(R,{variant:"text",size:"xs",onClick:y,disabled:c===s.contents,children:(0,a.jsx)(ka,{className:"h-3.5 w-3.5"})})})]})]})}),b=_e(v),N=!b&&v!=="text/csv";return(0,a.jsxs)(a.Fragment,{children:[d,N&&j&&(0,a.jsxs)(Pa,{variant:"warning",className:"rounded-none",children:[(0,a.jsx)(Fa,{className:"h-4 w-4"}),(0,a.jsx)(Ma,{children:"Editing the notebook file directly while running in marimo's editor may cause unintended changes. Please use with caution."})]}),(0,a.jsx)(Je,{mimeType:v,contents:b?void 0:N?c:s.contents??void 0,mediaSource:b?{base64:s.contents,mime:v}:void 0,readOnly:!N,onChange:x,extensions:[ea.of([{key:i.getHotkey("global.save").key,stopPropagation:!0,run:()=>c===s.contents?!1:(y(),!0)}])]})]})},Mt=Ue(t=>{let e=t(ta);return Ht(e,"no requestClientAtom set"),new fa({listFiles:e.sendListFiles,createFileOrFolder:e.sendCreateFileOrFolder,deleteFileOrFolder:e.sendDeleteFileOrFolder,copyFileOrFolder:e.sendCopyFileOrFolder,renameFileOrFolder:e.sendRenameFileOrFolder})}),dn=Ue({});async function mn(){await Rt.get(Mt).refreshAll([])}var le=" ";const Pt={directory:t=>`os.listdir("${t}")`,python:t=>`with open("${t}", "r") as _f:
11
- ${le}...
12
- `,json:t=>`with open("${t}", "r") as _f:
13
- ${le}_data = json.load(_f)
14
- `,code:t=>`with open("${t}", "r") as _f:
15
- ${le}...
16
- `,text:t=>`with open("${t}", "r") as _f:
17
- ${le}...
18
- `,image:t=>`mo.image("${t}")`,audio:t=>`mo.audio("${t}")`,video:t=>`mo.video("${t}")`,pdf:t=>`with open("${t}", "rb") as _f:
19
- ${le}...
20
- `,zip:t=>`with open("${t}", "rb") as _f:
21
- ${le}...
22
- `,data:t=>`with open("${t}", "r") as _f:
23
- ${le}...
24
- `,unknown:t=>`with open("${t}", "r") as _f:
25
- ${le}...
26
- `};var pn=fe(),hn=1024*1024*100,xn=5;function zt(t){let e=(0,pn.c)(7),n;e[0]===t?n=e[1]:(n=t===void 0?{}:t,e[0]=t,e[1]=n);let o=n,{sendCreateFileOrFolder:i}=ze(),r;e[2]===i?r=e[3]:(r=async c=>{if(c.length===0)return;let x=c.length===1;await Qt(x?"Uploading file...":"Uploading files...",async s=>{s.addTotal(c.length),await Aa(c,xn,async f=>{let h=bn(gn(f)),p="";h&&(p=Sa.guessDeliminator(h).dirname(h)),await i({path:p,type:"file",name:f.name,file:f}),s.increment(1)}),await mn()},{title:x?"File uploaded":`${c.length} files uploaded`})},e[2]=i,e[3]=r);let m;return e[4]!==o||e[5]!==r?(m={multiple:!0,maxSize:hn,onError:jn,onDropRejected:fn,onDrop:r,...o},e[4]=o,e[5]=r,e[6]=m):m=e[6],Ca(m)}function fn(t){te({title:"File upload failed",description:(0,a.jsx)("div",{className:"flex flex-col gap-1",children:t.map(un)}),variant:"danger"})}function un(t){return(0,a.jsxs)("div",{children:[t.file.name," (",t.errors.map(yn).join(", "),")"]},t.file.name)}function yn(t){return t.message}function jn(t){De.error(t),te({title:"File upload failed",description:t.message,variant:"danger"})}function gn(t){if(t.webkitRelativePath)return t.webkitRelativePath;if("path"in t&&typeof t.path=="string")return t.path;if("relativePath"in t&&typeof t.relativePath=="string")return t.relativePath}function bn(t){if(t)return t.replace(/^\/+/,"")}var be=fe(),vn=Ke("marimo:showHiddenFiles",!0,We,{getOnInit:!0}),Tt=$.createContext(null);const wn=t=>{let e=(0,be.c)(73),{height:n}=t,o=(0,$.useRef)(null),i=sn(),[r]=ke(Mt),m;e[0]===Symbol.for("react.memo_cache_sentinel")?(m=[],e[0]=m):m=e[0];let[c,x]=(0,$.useState)(m),[s,f]=(0,$.useState)(null),[h,p]=ke(vn),{openPrompt:g}=dt(),[y,w]=ke(dn),v;e[1]===r?v=e[2]:(v=()=>r.initialize(x),e[1]=r,e[2]=v);let l;e[3]===Symbol.for("react.memo_cache_sentinel")?(l=[],e[3]=l):l=e[3];let{isPending:j,error:d}=Ve(v,l),b;e[4]!==y||e[5]!==r?(b=()=>r.refreshAll(Object.keys(y).filter(k=>y[k])),e[4]=y,e[5]=r,e[6]=b):b=e[6];let N=ee(b),u;e[7]!==p||e[8]!==h?(u=()=>{p(!h)},e[7]=p,e[8]=h,e[9]=u):u=e[9];let F=ee(u),_;e[10]!==g||e[11]!==r?(_=async()=>{g({title:"Folder name",onConfirm:async k=>{r.createFolder(k,null)}})},e[10]=g,e[11]=r,e[12]=_):_=e[12];let C=ee(_),P;e[13]!==g||e[14]!==r?(P=async()=>{g({title:"File name",onConfirm:async k=>{r.createFile({name:k,parentId:null})}})},e[13]=g,e[14]=r,e[15]=P):P=e[15];let S=ee(P),D;e[16]!==g||e[17]!==r?(D=async()=>{g({title:"Notebook name",onConfirm:async k=>{r.createFile({name:k,parentId:null,type:"notebook"})}})},e[16]=g,e[17]=r,e[18]=D):D=e[18];let I=ee(D),T;e[19]===w?T=e[20]:(T=()=>{var k;(k=o.current)==null||k.closeAll(),w({})},e[19]=w,e[20]=T);let Q=ee(T),G;e[21]!==c||e[22]!==h?(G=Ot(c,h),e[21]=c,e[22]=h,e[23]=G):G=e[23];let oe=G;if(j){let k;return e[24]===Symbol.for("react.memo_cache_sentinel")?(k=(0,a.jsx)(ha,{size:"medium",centered:!0}),e[24]=k):k=e[24],k}if(d){let k;return e[25]===d?k=e[26]:(k=(0,a.jsx)(pt,{error:d}),e[25]=d,e[26]=k),k}if(s){let k;e[27]===Symbol.for("react.memo_cache_sentinel")?(k=()=>f(null),e[27]=k):k=e[27];let z;e[28]===Symbol.for("react.memo_cache_sentinel")?(z=(0,a.jsx)(R,{onClick:k,"data-testid":"file-explorer-back-button",variant:"text",size:"xs",className:"mb-0",children:(0,a.jsx)(Qe,{size:16})}),e[28]=z):z=e[28];let O;e[29]===s.name?O=e[30]:(O=(0,a.jsxs)("div",{className:"flex items-center pl-1 pr-3 shrink-0 border-b justify-between",children:[z,(0,a.jsx)("span",{className:"font-bold",children:s.name})]}),e[29]=s.name,e[30]=O);let K;e[31]!==s.path||e[32]!==r?(K=ne=>$t(ne,r.relativeFromRoot(s.path)),e[31]=s.path,e[32]=r,e[33]=K):K=e[33];let Y;e[34]!==s||e[35]!==K?(Y=(0,a.jsx)($.Suspense,{children:(0,a.jsx)(cn,{onOpenNotebook:K,file:s})}),e[34]=s,e[35]=K,e[36]=Y):Y=e[36];let Z;return e[37]!==O||e[38]!==Y?(Z=(0,a.jsxs)(a.Fragment,{children:[O,Y]}),e[37]=O,e[38]=Y,e[39]=Z):Z=e[39],Z}let E;e[40]!==Q||e[41]!==S||e[42]!==C||e[43]!==I||e[44]!==F||e[45]!==N||e[46]!==h||e[47]!==r?(E=(0,a.jsx)(kn,{onRefresh:N,onHidden:F,showHiddenFiles:h,onCreateFile:S,onCreateNotebook:I,onCreateFolder:C,onCollapseAll:Q,tree:r}),e[40]=Q,e[41]=S,e[42]=C,e[43]=I,e[44]=F,e[45]=N,e[46]=h,e[47]=r,e[48]=E):E=e[48];let X=n-33,B,H,L;e[49]===r?(B=e[50],H=e[51],L=e[52]):(B=async k=>{let{ids:z}=k;for(let O of z)await r.delete(O)},H=async k=>{let{id:z,name:O}=k;await r.rename(z,O)},L=async k=>{let{dragIds:z,parentId:O}=k;await r.move(z,O)},e[49]=r,e[50]=B,e[51]=H,e[52]=L);let J;e[53]===Symbol.for("react.memo_cache_sentinel")?(J=k=>{let z=k[0];z&&(z.data.isDirectory||f(z.data))},e[53]=J):J=e[53];let q;e[54]!==y||e[55]!==w||e[56]!==r?(q=async k=>{if(await r.expand(k)){let z=y[k]??!1;w({...y,[k]:!z})}},e[54]=y,e[55]=w,e[56]=r,e[57]=q):q=e[57];let U;e[58]!==i||e[59]!==y||e[60]!==X||e[61]!==B||e[62]!==H||e[63]!==L||e[64]!==q||e[65]!==oe?(U=(0,a.jsx)(ga,{width:"100%",ref:o,height:X,className:"h-full",data:oe,initialOpenState:y,openByDefault:!1,dndManager:i,renderCursor:Dn,disableDrop:Mn,onDelete:B,onRename:H,onMove:L,onSelect:J,onToggle:q,padding:15,rowHeight:30,indent:Nn,overscanCount:1e3,disableMultiSelection:!0,children:_n}),e[58]=i,e[59]=y,e[60]=X,e[61]=B,e[62]=H,e[63]=L,e[64]=q,e[65]=oe,e[66]=U):U=e[66];let W;e[67]!==U||e[68]!==r?(W=(0,a.jsx)(Tt,{value:r,children:U}),e[67]=U,e[68]=r,e[69]=W):W=e[69];let ae;return e[70]!==E||e[71]!==W?(ae=(0,a.jsxs)(a.Fragment,{children:[E,W]}),e[70]=E,e[71]=W,e[72]=ae):ae=e[72],ae};var Nn=15,kn=t=>{let e=(0,be.c)(37),{onRefresh:n,onHidden:o,showHiddenFiles:i,onCreateFile:r,onCreateNotebook:m,onCreateFolder:c,onCollapseAll:x}=t,s;e[0]===Symbol.for("react.memo_cache_sentinel")?(s={noDrag:!0,noDragEventsBubbling:!0},e[0]=s):s=e[0];let{getRootProps:f,getInputProps:h}=zt(s),p;e[1]===Symbol.for("react.memo_cache_sentinel")?(p=(0,a.jsx)(yt,{size:16}),e[1]=p):p=e[1];let g;e[2]===m?g=e[3]:(g=(0,a.jsx)(A,{content:"Add notebook",children:(0,a.jsx)(R,{"data-testid":"file-explorer-add-notebook-button",onClick:m,variant:"text",size:"xs",children:p})}),e[2]=m,e[3]=g);let y;e[4]===Symbol.for("react.memo_cache_sentinel")?(y=(0,a.jsx)(jt,{size:16}),e[4]=y):y=e[4];let w;e[5]===r?w=e[6]:(w=(0,a.jsx)(A,{content:"Add file",children:(0,a.jsx)(R,{"data-testid":"file-explorer-add-file-button",onClick:r,variant:"text",size:"xs",children:y})}),e[5]=r,e[6]=w);let v;e[7]===Symbol.for("react.memo_cache_sentinel")?(v=(0,a.jsx)(gt,{size:16}),e[7]=v):v=e[7];let l;e[8]===c?l=e[9]:(l=(0,a.jsx)(A,{content:"Add folder",children:(0,a.jsx)(R,{"data-testid":"file-explorer-add-folder-button",onClick:c,variant:"text",size:"xs",children:v})}),e[8]=c,e[9]=l);let j;e[10]===f?j=e[11]:(j=f({}),e[10]=f,e[11]=j);let d,b;e[12]===Symbol.for("react.memo_cache_sentinel")?(b=Xt({variant:"text",size:"xs"}),d=(0,a.jsx)(_a,{size:16}),e[12]=d,e[13]=b):(d=e[12],b=e[13]);let N;e[14]===j?N=e[15]:(N=(0,a.jsx)(A,{content:"Upload file",children:(0,a.jsx)("button",{"data-testid":"file-explorer-upload-button",...j,className:b,children:d})}),e[14]=j,e[15]=N);let u;e[16]===h?u=e[17]:(u=h({}),e[16]=h,e[17]=u);let F;e[18]===u?F=e[19]:(F=(0,a.jsx)("input",{...u,type:"file"}),e[18]=u,e[19]=F);let _;e[20]===n?_=e[21]:(_=(0,a.jsx)(et,{"data-testid":"file-explorer-refresh-button",onClick:n}),e[20]=n,e[21]=_);let C;e[22]!==o||e[23]!==i?(C=(0,a.jsx)(la,{"data-testid":"file-explorer-hidden-files-button",isVisible:i,onToggle:o,showTooltip:"Show hidden files",hideTooltip:"Hide hidden files"}),e[22]=o,e[23]=i,e[24]=C):C=e[24];let P;e[25]===Symbol.for("react.memo_cache_sentinel")?(P=(0,a.jsx)(Wa,{size:16}),e[25]=P):P=e[25];let S;e[26]===x?S=e[27]:(S=(0,a.jsx)(A,{content:"Collapse all folders",children:(0,a.jsx)(R,{"data-testid":"file-explorer-collapse-button",onClick:x,variant:"text",size:"xs",children:P})}),e[26]=x,e[27]=S);let D;return e[28]!==N||e[29]!==F||e[30]!==_||e[31]!==C||e[32]!==S||e[33]!==g||e[34]!==w||e[35]!==l?(D=(0,a.jsxs)("div",{className:"flex items-center justify-end px-2 shrink-0 border-b",children:[g,w,l,N,F,_,C,S]}),e[28]=N,e[29]=F,e[30]=_,e[31]=C,e[32]=S,e[33]=g,e[34]=w,e[35]=l,e[36]=D):D=e[36],D},Fn=t=>{let e=(0,be.c)(9),{node:n,onOpenMarimoFile:o}=t,i;e[0]===n?i=e[1]:(i=c=>{n.data.isDirectory||(c.stopPropagation(),n.select())},e[0]=n,e[1]=i);let r;e[2]!==n.data.isMarimoFile||e[3]!==o?(r=n.data.isMarimoFile&&!Fe()&&(0,a.jsxs)("span",{"data-testid":"file-explorer-open-marimo-button",className:"shrink-0 ml-2 text-sm hidden group-hover:inline hover:underline",onClick:o,children:["open ",(0,a.jsx)(Ie,{className:"inline ml-1",size:12})]}),e[2]=n.data.isMarimoFile,e[3]=o,e[4]=r):r=e[4];let m;return e[5]!==n.data.name||e[6]!==i||e[7]!==r?(m=(0,a.jsxs)("span",{className:"flex-1 overflow-hidden text-ellipsis",onClick:i,children:[n.data.name,r]}),e[5]=n.data.name,e[6]=i,e[7]=r,e[8]=m):m=e[8],m},_n=t=>{let e=(0,be.c)(116),{node:n,style:o,dragHandle:i}=t,{openFile:r,sendFileDetails:m}=ze(),c=ye(Ge),x;e[0]!==n.data.isDirectory||e[1]!==n.data.name?(x=n.data.isDirectory?"directory":da(n.data.name),e[0]=n.data.isDirectory,e[1]=n.data.name,e[2]=x):x=e[2];let s=x,f=ma[s],{openConfirm:h,openPrompt:p}=dt(),{createNewCell:g}=At(),y=za(),w;e[3]!==g||e[4]!==y?(w=M=>{g({code:M,before:!1,cellId:y??"__end__"})},e[3]=g,e[4]=y,e[5]=w):w=e[5];let v=w,l=(0,$.use)(Tt),j;e[6]!==n.data.path||e[7]!==l?(j=async M=>{$t(M,l?l.relativeFromRoot(n.data.path):n.data.path)},e[6]=n.data.path,e[7]=l,e[8]=j):j=e[8];let d=j,b;e[9]!==n.data.name||e[10]!==n.id||e[11]!==n.tree||e[12]!==h?(b=async M=>{M.stopPropagation(),M.preventDefault(),h({title:"Delete file",description:`Are you sure you want to delete ${n.data.name}?`,confirmAction:(0,a.jsx)(Wt,{onClick:async()=>{await n.tree.delete(n.id)},"aria-label":"Confirm",children:"Delete"})})},e[9]=n.data.name,e[10]=n.id,e[11]=n.tree,e[12]=h,e[13]=b):b=e[13];let N=b,u;e[14]!==n||e[15]!==p||e[16]!==l?(u=async()=>{n.open(),p({title:"Folder name",onConfirm:async M=>{l==null||l.createFolder(M,n.id)}})},e[14]=n,e[15]=p,e[16]=l,e[17]=u):u=e[17];let F=ee(u),_;e[18]!==n||e[19]!==p||e[20]!==l?(_=async()=>{n.open(),p({title:"File name",onConfirm:async M=>{l==null||l.createFile({name:M,parentId:n.id})}})},e[18]=n,e[19]=p,e[20]=l,e[21]=_):_=e[21];let C=ee(_),P;e[22]!==n||e[23]!==p||e[24]!==l?(P=async()=>{n.open(),p({title:"Notebook name",onConfirm:async M=>{l==null||l.createFile({name:M,parentId:n.id,type:"notebook"})}})},e[22]=n,e[23]=p,e[24]=l,e[25]=P):P=e[25];let S=ee(P),D;e[26]!==n.data.name||e[27]!==n.id||e[28]!==l?(D=async()=>{l&&await l.copy(n.id,Va(n.data.name))},e[26]=n.data.name,e[27]=n.id,e[28]=l,e[29]=D):D=e[29];let I=ee(D),T;e[30]===Symbol.for("react.memo_cache_sentinel")?(T=ie("flex items-center cursor-pointer ml-1 text-muted-foreground whitespace-nowrap group"),e[30]=T):T=e[30];let Q,G;e[31]===n?(Q=e[32],G=e[33]):(Q=M=>{M.stopPropagation(),n.data.isDirectory&&n.toggle()},G=(0,a.jsx)(Cn,{node:n}),e[31]=n,e[32]=Q,e[33]=G);let oe=n.willReceiveDrop&&n.data.isDirectory&&"bg-accent/80 hover:bg-accent/80 text-accent-foreground",E;e[34]===oe?E=e[35]:(E=ie("flex items-center pl-1 py-1 cursor-pointer hover:bg-accent/50 hover:text-accent-foreground rounded-l flex-1 overflow-hidden group",oe),e[34]=oe,e[35]=E);let X;e[36]!==f||e[37]!==s||e[38]!==n.data.isMarimoFile?(X=n.data.isMarimoFile?(0,a.jsx)(La,{className:"w-5 h-5 shrink-0 mr-2",strokeWidth:1.5}):(0,a.jsx)(f,{className:ie("w-5 h-5 shrink-0 mr-2",nt[s]),strokeWidth:1.5}),e[36]=f,e[37]=s,e[38]=n.data.isMarimoFile,e[39]=X):X=e[39];let B;e[40]!==d||e[41]!==n?(B=n.isEditing?(0,a.jsx)(wa,{node:n}):(0,a.jsx)(Fn,{node:n,onOpenMarimoFile:d}),e[40]=d,e[41]=n,e[42]=B):B=e[42];let H;e[43]===n?H=e[44]:(H=!n.data.isDirectory&&(0,a.jsxs)(V,{onSelect:()=>n.select(),"data-testid":"file-explorer-open-file-menu-item",children:[(0,a.jsx)(vt,{className:"h-3.5 w-3.5 mr-2"}),"Open file"]}),e[43]=n,e[44]=H);let L;e[45]!==n.data.isDirectory||e[46]!==n.data.path||e[47]!==r?(L=!n.data.isDirectory&&!Fe()&&(0,a.jsxs)(V,{onSelect:()=>{r({path:n.data.path})},"data-testid":"file-explorer-open-external-menu-item",children:[(0,a.jsx)(Ie,{className:"h-3.5 w-3.5 mr-2"}),"Open file in external editor"]}),e[45]=n.data.isDirectory,e[46]=n.data.path,e[47]=r,e[48]=L):L=e[48];let J;e[49]!==C||e[50]!==F||e[51]!==S||e[52]!==n.data.isDirectory?(J=n.data.isDirectory&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(V,{onSelect:()=>S(),"data-testid":"file-explorer-create-notebook-menu-item",children:[(0,a.jsx)(yt,{className:"h-3.5 w-3.5 mr-2"}),"Create notebook"]}),(0,a.jsxs)(V,{onSelect:()=>C(),"data-testid":"file-explorer-create-file-menu-item",children:[(0,a.jsx)(jt,{className:"h-3.5 w-3.5 mr-2"}),"Create file"]}),(0,a.jsxs)(V,{onSelect:()=>F(),"data-testid":"file-explorer-create-folder-menu-item",children:[(0,a.jsx)(gt,{className:"h-3.5 w-3.5 mr-2"}),"Create folder"]}),(0,a.jsx)(ue,{})]}),e[49]=C,e[50]=F,e[51]=S,e[52]=n.data.isDirectory,e[53]=J):J=e[53];let q;e[54]===n?q=e[55]:(q=(0,a.jsx)(xa,{onSelect:()=>n.edit(),testId:"file-explorer-rename-menu-item"}),e[54]=n,e[55]=q);let U;e[56]===I?U=e[57]:(U=(0,a.jsx)(va,{onSelect:I,testId:"file-explorer-duplicate-menu-item"}),e[56]=I,e[57]=U);let W;e[58]===n.data.path?W=e[59]:(W=async()=>{await ge(n.data.path),te({title:"Copied to clipboard"})},e[58]=n.data.path,e[59]=W);let ae;e[60]===Symbol.for("react.memo_cache_sentinel")?(ae=(0,a.jsx)(bt,{className:je}),e[60]=ae):ae=e[60];let k;e[61]===W?k=e[62]:(k=(0,a.jsxs)(V,{onSelect:W,"data-testid":"file-explorer-copy-path-menu-item",children:[ae,"Copy path"]}),e[61]=W,e[62]=k);let z;e[63]!==n.data.path||e[64]!==l?(z=l&&(0,a.jsxs)(V,{onSelect:async()=>{await ge(l.relativeFromRoot(n.data.path)),te({title:"Copied to clipboard"})},"data-testid":"file-explorer-copy-relative-path-menu-item",children:[(0,a.jsx)(bt,{className:"h-3.5 w-3.5 mr-2"}),"Copy relative path"]}),e[63]=n.data.path,e[64]=l,e[65]=z):z=e[65];let O;e[66]===Symbol.for("react.memo_cache_sentinel")?(O=(0,a.jsx)(ue,{}),e[66]=O):O=e[66];let K;e[67]!==s||e[68]!==v||e[69]!==n.data?(K=()=>{let{path:M}=n.data;v(Pt[s](M))},e[67]=s,e[68]=v,e[69]=n.data,e[70]=K):K=e[70];let Y;e[71]===Symbol.for("react.memo_cache_sentinel")?(Y=(0,a.jsx)(ra,{className:je}),e[71]=Y):Y=e[71];let Z;e[72]===K?Z=e[73]:(Z=(0,a.jsxs)(V,{onSelect:K,"data-testid":"file-explorer-insert-snippet-menu-item",children:[Y,"Insert snippet for reading file"]}),e[72]=K,e[73]=Z);let ne;e[74]!==s||e[75]!==n.data?(ne=async()=>{te({title:"Copied to clipboard",description:"Code to open the file has been copied to your clipboard. You can also drag and drop this file into the editor"});let{path:M}=n.data;await ge(Pt[s](M))},e[74]=s,e[75]=n.data,e[76]=ne):ne=e[76];let ve;e[77]===Symbol.for("react.memo_cache_sentinel")?(ve=(0,a.jsx)(Bt,{className:je}),e[77]=ve):ve=e[77];let ce;e[78]===ne?ce=e[79]:(ce=(0,a.jsxs)(V,{onSelect:ne,"data-testid":"file-explorer-copy-snippet-menu-item",children:[ve,"Copy snippet for reading file"]}),e[78]=ne,e[79]=ce);let de;e[80]!==d||e[81]!==n.data.isMarimoFile?(de=n.data.isMarimoFile&&!Fe()&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(ue,{}),(0,a.jsxs)(V,{onSelect:d,"data-testid":"file-explorer-open-notebook-menu-item",children:[(0,a.jsx)(Ga,{className:"h-3.5 w-3.5 mr-2"}),"Open notebook"]})]}),e[80]=d,e[81]=n.data.isMarimoFile,e[82]=de):de=e[82];let we;e[83]===Symbol.for("react.memo_cache_sentinel")?(we=(0,a.jsx)(ue,{}),e[83]=we):we=e[83];let me;e[84]!==c||e[85]!==n.data.isDirectory||e[86]!==n.data.name||e[87]!==n.data.path||e[88]!==m?(me=!n.data.isDirectory&&!c&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(V,{onSelect:async()=>{let M=await m({path:n.data.path});M.isBase64&&M.contents?Ce(mt(Oe(M.contents,M.mimeType||"application/octet-stream")),n.data.name):Ce(new Blob([M.contents||""]),n.data.name)},"data-testid":"file-explorer-download-menu-item",children:[(0,a.jsx)(Me,{className:"h-3.5 w-3.5 mr-2"}),"Download"]}),(0,a.jsx)(ue,{})]}),e[84]=c,e[85]=n.data.isDirectory,e[86]=n.data.name,e[87]=n.data.path,e[88]=m,e[89]=me):me=e[89];let pe;e[90]===N?pe=e[91]:(pe=(0,a.jsx)(ba,{onSelect:N,testId:"file-explorer-delete-menu-item"}),e[90]=N,e[91]=pe);let he;e[92]!==H||e[93]!==L||e[94]!==J||e[95]!==q||e[96]!==U||e[97]!==k||e[98]!==z||e[99]!==Z||e[100]!==ce||e[101]!==de||e[102]!==me||e[103]!==pe?(he=(0,a.jsxs)(ja,{testId:"file-explorer-more-button",iconClassName:"w-5 h-5",children:[H,L,J,q,U,k,z,O,Z,ce,de,we,me,pe]}),e[92]=H,e[93]=L,e[94]=J,e[95]=q,e[96]=U,e[97]=k,e[98]=z,e[99]=Z,e[100]=ce,e[101]=de,e[102]=me,e[103]=pe,e[104]=he):he=e[104];let xe;e[105]!==E||e[106]!==X||e[107]!==B||e[108]!==he?(xe=(0,a.jsxs)("span",{className:E,children:[X,B,he]}),e[105]=E,e[106]=X,e[107]=B,e[108]=he,e[109]=xe):xe=e[109];let Ne;return e[110]!==i||e[111]!==o||e[112]!==Q||e[113]!==G||e[114]!==xe?(Ne=(0,a.jsxs)("div",{style:o,ref:i,className:T,draggable:!0,onClick:Q,children:[G,xe]}),e[110]=i,e[111]=o,e[112]=Q,e[113]=G,e[114]=xe,e[115]=Ne):Ne=e[115],Ne},Cn=t=>{let e=(0,be.c)(3),{node:n}=t;if(!n.data.isDirectory){let i;return e[0]===Symbol.for("react.memo_cache_sentinel")?(i=(0,a.jsx)("span",{className:"w-4 h-4 shrink-0"}),e[0]=i):i=e[0],i}let o;return e[1]===n.isOpen?o=e[2]:(o=(0,a.jsx)($e,{isExpanded:n.isOpen,className:"w-4 h-4"}),e[1]=n.isOpen,e[2]=o),o};function $t(t,e){t.stopPropagation(),t.preventDefault(),qa(e)}function Ot(t,e){if(e)return t;let n=[];for(let o of t){if(Sn(o.name))continue;let i=o;if(o.children){let r=Ot(o.children,e);r!==o.children&&(i={...o,children:r})}n.push(i)}return n}function Sn(t){return!!t.startsWith(".")}function Dn(){return null}function Mn(t){let{parentNode:e}=t;return!e.data.isDirectory}var It=fe(),Pn=Ke("marimo:file-explorer-panel:state",{openSections:["files"],hasUserInteracted:!1},We),zn=t=>{let e=(0,It.c)(20),{height:n}=t,o;e[0]===Symbol.for("react.memo_cache_sentinel")?(o={noClick:!0,noKeyboard:!0},e[0]=o):o=e[0];let{getRootProps:i,getInputProps:r,isDragActive:m}=zt(o),c;e[1]===i?c=e[2]:(c=i(),e[1]=i,e[2]=c);let x;e[3]===Symbol.for("react.memo_cache_sentinel")?(x=ie("flex flex-col overflow-hidden relative"),e[3]=x):x=e[3];let s;e[4]===n?s=e[5]:(s={height:n},e[4]=n,e[5]=s);let f;e[6]===r?f=e[7]:(f=r(),e[6]=r,e[7]=f);let h;e[8]===f?h=e[9]:(h=(0,a.jsx)("input",{...f}),e[8]=f,e[9]=h);let p;e[10]===m?p=e[11]:(p=m&&(0,a.jsx)("div",{className:"absolute inset-0 flex items-center uppercase justify-center text-xl font-bold text-primary/90 bg-accent/85 z-10 border-2 border-dashed border-primary/90 rounded-lg pointer-events-none",children:"Drop files here"}),e[10]=m,e[11]=p);let g;e[12]===n?g=e[13]:(g=(0,a.jsx)(wn,{height:n}),e[12]=n,e[13]=g);let y;return e[14]!==c||e[15]!==s||e[16]!==h||e[17]!==p||e[18]!==g?(y=(0,a.jsx)(on,{children:(0,a.jsxs)("div",{...c,className:x,style:s,children:[h,p,g]})}),e[14]=c,e[15]=s,e[16]=h,e[17]=p,e[18]=g,e[19]=y):y=e[19],y},Tn=33,$n=()=>{let t=(0,It.c)(36),{ref:e,height:n}=Ra(),o=n===void 0?500:n,[i,r]=ke(Pn),m=ye(na).length,c;e:{if(!i.hasUserInteracted&&m>0){if(i.openSections.includes("remote-storage")){c=i.openSections;break e}let T;t[0]===i.openSections?T=t[1]:(T=[...i.openSections,"remote-storage"],t[0]=i.openSections,t[1]=T),c=T;break e}c=i.openSections}let x=c,s;t[2]===r?s=t[3]:(s=T=>{r({openSections:T,hasUserInteracted:!0})},t[2]=r,t[3]=s);let f=s,h=o-Tn*2,p;t[4]===x?p=t[5]:(p=x.includes("remote-storage"),t[4]=x,t[5]=p);let g=p,y;t[6]!==x||t[7]!==g?(y=g&&x.includes("files"),t[6]=x,t[7]=g,t[8]=y):y=t[8];let w=y,v;t[9]!==h||t[10]!==w?(v=w?Math.round(h*.4):h,t[9]=h,t[10]=w,t[11]=v):v=t[11];let l=v,j=Math.max(200,w?h-l:h),d;t[12]===Symbol.for("react.memo_cache_sentinel")?(d=(0,a.jsx)(st,{className:"w-4 h-4"}),t[12]=d):d=t[12];let b;t[13]===m?b=t[14]:(b=m>0&&(0,a.jsx)(Ha,{children:m}),t[13]=m,t[14]=b);let N;t[15]===b?N=t[16]:(N=(0,a.jsxs)(ft,{children:[d," Remote storage",b]}),t[15]=b,t[16]=N);let u;t[17]===l?u=t[18]:(u={maxHeight:l},t[17]=l,t[18]=u);let F;t[19]===Symbol.for("react.memo_cache_sentinel")?(F=(0,a.jsx)(rn,{}),t[19]=F):F=t[19];let _;t[20]===u?_=t[21]:(_=(0,a.jsx)(ut,{className:"overflow-auto",style:u,children:F}),t[20]=u,t[21]=_);let C;t[22]!==_||t[23]!==N?(C=(0,a.jsxs)(xt,{value:"remote-storage",children:[N,_]}),t[22]=_,t[23]=N,t[24]=C):C=t[24];let P;t[25]===Symbol.for("react.memo_cache_sentinel")?(P=(0,a.jsxs)(ft,{children:[(0,a.jsx)(rt,{className:"w-4 h-4"}),"Files"]}),t[25]=P):P=t[25];let S;t[26]===j?S=t[27]:(S=(0,a.jsxs)(xt,{value:"files",children:[P,(0,a.jsx)(ut,{children:(0,a.jsx)(zn,{height:j})})]}),t[26]=j,t[27]=S);let D;t[28]!==f||t[29]!==x||t[30]!==C||t[31]!==S?(D=(0,a.jsxs)(Ut,{type:"multiple",value:x,onValueChange:f,children:[C,S]}),t[28]=f,t[29]=x,t[30]=C,t[31]=S,t[32]=D):D=t[32];let I;return t[33]!==e||t[34]!==D?(I=(0,a.jsx)("div",{ref:e,className:"h-full overflow-auto",children:D}),t[33]=e,t[34]=D,t[35]=I):I=t[35],I};export{$n as default};
@@ -1 +0,0 @@
1
- import{p as E,u as b}from"./useEvent-D91BmmQi.js";import{t as k}from"./compiler-runtime-B3qBwwSJ.js";import{t as q}from"./createReducer-CI9qeK_X.js";import{t as y}from"./requests-DIwGYs0l.js";import{t as A}from"./createLucideIcon-D5guW7EU.js";import{t as g}from"./DeferredRequestRegistry-CNldVcrP.js";import{n as $}from"./useAsyncData-bgszE9F0.js";var I=A("arrow-left",[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]]);const v=new g("storage-list-entries",async(r,t)=>{await y().listStorageEntries({requestId:r,...t})}),N=new g("storage-download",async(r,t)=>{await y().downloadStorage({requestId:r,...t})});function w(r,t){return`${r}::${t??""}`}function _(r){return`${r}::`}var z=k();function C(){return{namespaces:[],entriesByPath:new Map}}var{reducer:O,createActions:Q,valueAtom:P,useActions:F}=q(C,{setNamespaces:(r,t)=>{let e=new Map(r.namespaces.map(a=>[a.name,a]));for(let a of t.namespaces)e.set(a.name,a);return{...r,namespaces:[...e.values()]}},setEntries:(r,t)=>{let e=w(t.namespace,t.prefix),a=new Map(r.entriesByPath);return a.set(e,t.entries),{...r,entriesByPath:a}},clearNamespaceCache:(r,t)=>{let e=new Map(r.entriesByPath),a=_(t);for(let n of e.keys())n.startsWith(a)&&e.delete(n);return{...r,entriesByPath:e}},filterFromVariables:(r,t)=>{let e=new Set(t),a=r.namespaces.filter(n=>e.has(n.name));return{...r,namespaces:a}}});const x=()=>b(P),H=E(r=>r(P).namespaces);function B(){return F()}function V(r,t){let e=(0,z.c)(20),{entriesByPath:a}=x(),{setEntries:n}=B(),o;e[0]!==a||e[1]!==r||e[2]!==t?(o=a.get(w(r,t)),e[0]=a,e[1]=r,e[2]=t,e[3]=o):o=e[3];let s=o,m;e[4]!==s||e[5]!==r||e[6]!==t||e[7]!==n?(m=async()=>{if(s)return;let d=await v.request({namespace:r,prefix:t??"",limit:150});if(d.error)throw Error(d.error);n({namespace:r,prefix:t,entries:d.entries})},e[4]=s,e[5]=r,e[6]=t,e[7]=n,e[8]=m):m=e[8];let f=s===void 0,c;e[9]!==r||e[10]!==t||e[11]!==f?(c=[r,t,f],e[9]=r,e[10]=t,e[11]=f,e[12]=c):c=e[12];let{isPending:M,error:S,refetch:l}=$(m,c),i;e[13]===s?i=e[14]:(i=s??[],e[13]=s,e[14]=i);let u=M&&!s,h=s?void 0:S,p;return e[15]!==l||e[16]!==i||e[17]!==u||e[18]!==h?(p={entries:i,isPending:u,error:h,refetch:l},e[15]=l,e[16]=i,e[17]=u,e[18]=h,e[19]=p):p=e[19],p}export{w as a,I as c,V as i,x as n,N as o,B as r,v as s,H as t};