@mountra/mountra-sdk 0.2.0 → 0.4.0

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/index.d.cts CHANGED
@@ -1,3 +1,129 @@
1
+ /**
2
+ * Per-download cache behavior, modelled on `RequestInit.cache`:
3
+ * - `default`: serve a fresh cached file without contacting Mountra; otherwise
4
+ * export it and reuse any cached chunks.
5
+ * - `no-cache`: always export first, but still reuse cached chunks.
6
+ * - `no-store`: neither read from nor write to the cache.
7
+ */
8
+ type DownloadCacheMode = "default" | "no-cache" | "no-store";
9
+ interface DownloadCacheOptions {
10
+ /** Upper bound of cached chunk bytes, shared by all workspaces. Defaults to 512 MiB. */
11
+ maxBytes?: number;
12
+ /**
13
+ * Chunks larger than this are never cached, because a downloaded chunk is
14
+ * buffered in memory before it is stored. Defaults to 128 MiB and never
15
+ * exceeds `maxBytes`.
16
+ */
17
+ maxChunkBytes?: number;
18
+ /**
19
+ * How long a downloaded file may be served from the cache without asking
20
+ * Mountra whether it changed. Defaults to 5 minutes; 0 always revalidates.
21
+ */
22
+ ttlMs?: number;
23
+ /** Cache storage. Defaults to IndexedDB, or memory when IndexedDB is unavailable. */
24
+ store?: DownloadCacheStore;
25
+ }
26
+ interface DownloadCacheChunk {
27
+ index: number;
28
+ offset: number;
29
+ size: number;
30
+ storageKey: string;
31
+ }
32
+ /** The chunk layout of one file. Signed URLs are never cached. */
33
+ interface DownloadCacheFile {
34
+ path: string;
35
+ size: number;
36
+ contentType?: string;
37
+ chunks: DownloadCacheChunk[];
38
+ /** When Mountra last confirmed this layout. */
39
+ cachedAt: number;
40
+ /** After this time the layout must be confirmed by Mountra again. */
41
+ expiresAt: number;
42
+ }
43
+ interface DownloadCacheUsage {
44
+ bytes: number;
45
+ chunks: number;
46
+ }
47
+ /**
48
+ * Storage behind the download cache. Every entry is scoped by an opaque
49
+ * workspace key, so one workspace never observes another workspace's entries.
50
+ */
51
+ interface DownloadCacheStore {
52
+ getFile(workspace: string, fileKey: string): Promise<DownloadCacheFile | null>;
53
+ putFile(workspace: string, fileKey: string, file: DownloadCacheFile): Promise<void>;
54
+ removeFile(workspace: string, fileKey: string): Promise<void>;
55
+ /**
56
+ * Remove every file whose `path` is `path` or below it, keeping the chunks.
57
+ * Optional: without it, a move or delete through the client clears the
58
+ * whole workspace instead.
59
+ */
60
+ removeFilesUnder?(workspace: string, path: string): Promise<void>;
61
+ /** Return the chunk bytes and mark the chunk as most recently used. */
62
+ getChunk(workspace: string, storageKey: string): Promise<Blob | null>;
63
+ /** Store the chunk bytes, then evict least recently used chunks until at most `maxBytes` remain. */
64
+ putChunk(workspace: string, storageKey: string, data: Blob, maxBytes: number): Promise<void>;
65
+ /** Remove every entry, or only the entries of one workspace. */
66
+ clear(workspace?: string): Promise<void>;
67
+ usage(workspace?: string): Promise<DownloadCacheUsage>;
68
+ }
69
+ declare class InMemoryDownloadCacheStore implements DownloadCacheStore {
70
+ private readonly files;
71
+ /** Map iteration order is the LRU order: the first entry is the least recently used. */
72
+ private readonly chunks;
73
+ private bytes;
74
+ getFile(workspace: string, fileKey: string): Promise<DownloadCacheFile | null>;
75
+ putFile(workspace: string, fileKey: string, file: DownloadCacheFile): Promise<void>;
76
+ removeFile(workspace: string, fileKey: string): Promise<void>;
77
+ removeFilesUnder(workspace: string, path: string): Promise<void>;
78
+ getChunk(workspace: string, storageKey: string): Promise<Blob | null>;
79
+ putChunk(workspace: string, storageKey: string, data: Blob, maxBytes: number): Promise<void>;
80
+ clear(workspace?: string): Promise<void>;
81
+ usage(workspace?: string): Promise<DownloadCacheUsage>;
82
+ private removeChunk;
83
+ }
84
+ interface IndexedDBDownloadCacheStoreOptions {
85
+ /** Use a separate database, for example one per signed-in user. */
86
+ databaseName?: string;
87
+ }
88
+ declare class IndexedDBDownloadCacheStore implements DownloadCacheStore {
89
+ private readonly databaseName;
90
+ private readonly fallback;
91
+ private databasePromise?;
92
+ constructor(options?: IndexedDBDownloadCacheStoreOptions);
93
+ getFile(workspace: string, fileKey: string): Promise<DownloadCacheFile | null>;
94
+ putFile(workspace: string, fileKey: string, file: DownloadCacheFile): Promise<void>;
95
+ removeFile(workspace: string, fileKey: string): Promise<void>;
96
+ removeFilesUnder(workspace: string, path: string): Promise<void>;
97
+ getChunk(workspace: string, storageKey: string): Promise<Blob | null>;
98
+ putChunk(workspace: string, storageKey: string, data: Blob, maxBytes: number): Promise<void>;
99
+ clear(workspace?: string): Promise<void>;
100
+ usage(workspace?: string): Promise<DownloadCacheUsage>;
101
+ private openDatabase;
102
+ }
103
+ /** Cache policy of one client. Cache failures degrade to misses and never fail a download. */
104
+ declare class DownloadCache {
105
+ readonly maxBytes: number;
106
+ readonly maxChunkBytes: number;
107
+ readonly ttlMs: number;
108
+ private readonly store;
109
+ constructor(options: DownloadCacheOptions);
110
+ /** Return a file that has not expired together with all of its chunk bytes. */
111
+ loadFile(workspace: string, fileKey: string): Promise<{
112
+ file: DownloadCacheFile;
113
+ chunks: Map<number, Blob>;
114
+ } | null>;
115
+ readChunk(workspace: string, chunk: DownloadCacheChunk): Promise<Blob | null>;
116
+ canStoreChunk(chunk: DownloadCacheChunk): boolean;
117
+ /** Returns whether the chunk is now cached. */
118
+ storeChunk(workspace: string, chunk: DownloadCacheChunk, data: Blob): Promise<boolean>;
119
+ storeFile(workspace: string, fileKey: string, file: Omit<DownloadCacheFile, "cachedAt" | "expiresAt">): Promise<void>;
120
+ invalidateFiles(workspace: string, fileKeys: string[]): Promise<void>;
121
+ /** Drop the files at or below `paths`, which a write changed; their chunks stay cached. */
122
+ invalidatePaths(workspace: string, paths: string[]): Promise<void>;
123
+ clear(workspace?: string): Promise<void>;
124
+ usage(workspace?: string): Promise<DownloadCacheUsage>;
125
+ }
126
+
1
127
  interface FileSystemWritableFileStreamLike {
2
128
  write(data: Uint8Array | Blob): Promise<void>;
3
129
  seek(position: number): Promise<void>;
@@ -67,6 +193,8 @@ interface DownloadFileOptions extends ExportFileOptions {
67
193
  onProgress?: (progress: DownloadProgress) => void;
68
194
  /** Use a previously selected file handle, primarily for resumeDownload. */
69
195
  fileHandle?: FileSystemFileHandleLike;
196
+ /** How this download uses the client's `downloadCache`. Defaults to `default`. */
197
+ cache?: DownloadCacheMode;
70
198
  }
71
199
  interface DownloadResumeOptions {
72
200
  signal?: AbortSignal;
@@ -75,9 +203,12 @@ interface DownloadResumeOptions {
75
203
  onProgress?: (progress: DownloadProgress) => void;
76
204
  }
77
205
  interface DownloadResult {
78
- export: ExportFileResponse;
206
+ /** Absent when the file was served from the download cache without contacting Mountra. */
207
+ export?: ExportFileResponse;
79
208
  downloadKey: string;
80
209
  downloadedBytes: number;
210
+ /** Bytes served from the download cache instead of the network. */
211
+ cachedBytes: number;
81
212
  resumed: boolean;
82
213
  fileHandle?: FileSystemFileHandleLike;
83
214
  blob?: Blob;
@@ -142,6 +273,7 @@ interface DownloadTransport {
142
273
  readonly clientSelector: WorkspaceSelector;
143
274
  readonly fetchImpl: typeof globalThis.fetch;
144
275
  readonly checkpointStore: DownloadCheckpointStore;
276
+ readonly cache: DownloadCache | null;
145
277
  requestJson(path: string, body: unknown, signal?: AbortSignal): Promise<unknown>;
146
278
  }
147
279
  declare class MountraDownloader {
@@ -153,6 +285,37 @@ declare class MountraDownloader {
153
285
  resumeDownload(downloadKey: string, options?: DownloadResumeOptions): Promise<DownloadResult>;
154
286
  listResumableDownloads(): Promise<DownloadCheckpoint[]>;
155
287
  clearDownloadCheckpoint(downloadKey: string): Promise<void>;
288
+ /** Drop the cached layout of a file that was just written, so the next download sees the new content. */
289
+ invalidateCachedFile(selector: WorkspaceSelector, target: {
290
+ path?: string;
291
+ ino?: number | string;
292
+ }): Promise<void>;
293
+ /** Drop the cached files at or below paths that a delete, move, or copy changed. */
294
+ invalidateCachedPaths(selector: WorkspaceSelector, paths: string[]): Promise<void>;
295
+ /**
296
+ * Cache a file this client just uploaded, so downloading it needs no
297
+ * network. Falls back to invalidation when any chunk cannot be cached.
298
+ */
299
+ cacheUploadedFile(selector: WorkspaceSelector, file: {
300
+ path: string;
301
+ ino?: number | string;
302
+ size: number;
303
+ contentType?: string;
304
+ chunks: Array<DownloadCacheChunk & {
305
+ data: Blob;
306
+ }>;
307
+ }, mode?: Exclude<DownloadCacheMode, "no-cache">): Promise<void>;
308
+ private cachedFileScope;
309
+ clearCache(selector?: WorkspaceSelector): Promise<void>;
310
+ cacheUsage(selector?: WorkspaceSelector): Promise<DownloadCacheUsage>;
311
+ private requireCacheWorkspace;
312
+ /** Fall back to the client workspace only when the request names none, as uploads do. */
313
+ private resolveRequest;
314
+ private exportRequest;
315
+ private cacheScope;
316
+ /** A plan that needs no network at all, when the cached layout is fresh and every chunk is cached. */
317
+ private loadCachedPlan;
318
+ private planExport;
156
319
  private pickSaveFile;
157
320
  private ensureWritePermission;
158
321
  private downloadResolved;
@@ -197,6 +360,197 @@ declare class MountraFile {
197
360
  resume(options?: MountraFileResumeOptions): Promise<DownloadResult>;
198
361
  }
199
362
 
363
+ type MetadataCacheKind = "list" | "tree";
364
+ /** A cached `list` result: the entries of one directory. */
365
+ interface MetadataListRecord {
366
+ kind: "list";
367
+ path: string;
368
+ entries: MountraFileEntry[];
369
+ /**
370
+ * When the request that returned this result was sent. Writes through this
371
+ * client and overlapping fetches may have updated the record since.
372
+ */
373
+ fetchedAt: number;
374
+ }
375
+ /** A cached `tree` result: one directory and its complete subtree. */
376
+ interface MetadataTreeRecord {
377
+ kind: "tree";
378
+ path: string;
379
+ root: MountraFileTreeNode;
380
+ /** See `MetadataListRecord.fetchedAt`. */
381
+ fetchedAt: number;
382
+ }
383
+ type MetadataCacheRecord = MetadataListRecord | MetadataTreeRecord;
384
+ interface MetadataCacheBatch {
385
+ put: MetadataCacheRecord[];
386
+ remove: Array<{
387
+ kind: MetadataCacheKind;
388
+ path: string;
389
+ }>;
390
+ }
391
+ interface MetadataCacheOptions {
392
+ /**
393
+ * Upper bound of cached `list` and `tree` results, shared by all
394
+ * workspaces. A tree counts as one result however large it is. Defaults to
395
+ * 1000; the least recently refreshed results are evicted first.
396
+ */
397
+ maxEntries?: number;
398
+ /** Cache storage. Defaults to IndexedDB, or memory when IndexedDB is unavailable. */
399
+ store?: MetadataCacheStore;
400
+ }
401
+ /**
402
+ * Storage behind the metadata cache. A record is identified by an opaque
403
+ * workspace key together with its `kind` and `path`, so one workspace never
404
+ * observes another workspace's records.
405
+ */
406
+ interface MetadataCacheStore {
407
+ get(workspace: string, kind: MetadataCacheKind, path: string): Promise<MetadataCacheRecord | null>;
408
+ /** The records stored at `path` or at any path below it, of one kind or of both. */
409
+ getSubtree(workspace: string, path: string, kind?: MetadataCacheKind): Promise<MetadataCacheRecord[]>;
410
+ /** Apply the batch atomically, then evict the least recently written records until at most `maxEntries` remain. */
411
+ write(workspace: string, batch: MetadataCacheBatch, maxEntries: number): Promise<void>;
412
+ /** Remove every record, or only the records of one workspace. */
413
+ clear(workspace?: string): Promise<void>;
414
+ }
415
+ declare class InMemoryMetadataCacheStore implements MetadataCacheStore {
416
+ /** Map iteration order is the eviction order: the first entry was written least recently. */
417
+ private readonly records;
418
+ get(workspace: string, kind: MetadataCacheKind, path: string): Promise<MetadataCacheRecord | null>;
419
+ getSubtree(workspace: string, path: string, kind?: MetadataCacheKind): Promise<MetadataCacheRecord[]>;
420
+ write(workspace: string, batch: MetadataCacheBatch, maxEntries: number): Promise<void>;
421
+ clear(workspace?: string): Promise<void>;
422
+ }
423
+ interface IndexedDBMetadataCacheStoreOptions {
424
+ /** Use a separate database, for example one per signed-in user. */
425
+ databaseName?: string;
426
+ }
427
+ /** Records are keyed `[workspace, kind, path]`, so a subtree of one kind is one key range. */
428
+ declare class IndexedDBMetadataCacheStore implements MetadataCacheStore {
429
+ private readonly databaseName;
430
+ private readonly fallback;
431
+ private databasePromise?;
432
+ constructor(options?: IndexedDBMetadataCacheStoreOptions);
433
+ get(workspace: string, kind: MetadataCacheKind, path: string): Promise<MetadataCacheRecord | null>;
434
+ getSubtree(workspace: string, path: string, kind?: MetadataCacheKind): Promise<MetadataCacheRecord[]>;
435
+ write(workspace: string, batch: MetadataCacheBatch, maxEntries: number): Promise<void>;
436
+ clear(workspace?: string): Promise<void>;
437
+ private openDatabase;
438
+ }
439
+
440
+ /** One entry of a directory listing. */
441
+ interface MountraFileEntry {
442
+ name: string;
443
+ /** Absolute path in the workspace. */
444
+ path: string;
445
+ ino: number;
446
+ isDirectory: boolean;
447
+ size: number;
448
+ mtimeMs: number;
449
+ atimeMs: number;
450
+ uid?: number;
451
+ gid?: number;
452
+ uidDisplayName?: string;
453
+ uidUsername?: string;
454
+ uidSubjectId?: string;
455
+ uidSubjectType?: string;
456
+ gidDisplayName?: string;
457
+ gidUsername?: string;
458
+ gidSubjectId?: string;
459
+ gidSubjectType?: string;
460
+ }
461
+ /** A node of a file tree. A directory node holds its complete subtree. */
462
+ interface MountraFileTreeNode {
463
+ name: string;
464
+ /** Absolute path in the workspace. */
465
+ path: string;
466
+ ino: number;
467
+ isDirectory: boolean;
468
+ size: number;
469
+ mtimeMs: number;
470
+ uid?: number;
471
+ gid?: number;
472
+ uidSubjectId?: string;
473
+ uidSubjectType?: string;
474
+ gidSubjectId?: string;
475
+ gidSubjectType?: string;
476
+ children: MountraFileTreeNode[];
477
+ }
478
+ /**
479
+ * How a metadata read uses the client's `metadataCache`:
480
+ * - `sync`: wait for Mountra and return its result.
481
+ * - `async`: return the cached result at once and refresh it in the
482
+ * background. Without a cached result, wait for Mountra as `sync` does.
483
+ *
484
+ * Either way, a result fetched from Mountra is cached before it is returned.
485
+ */
486
+ type MetadataReadMode = "sync" | "async";
487
+ /** `cache` when the result was served from the metadata cache, `remote` when Mountra just returned it. */
488
+ type MetadataSource = "cache" | "remote";
489
+ interface MetadataReadOptions<T> extends WorkspaceSelector {
490
+ /** The directory to read. Defaults to `/`. */
491
+ path?: string;
492
+ /** Defaults to `sync`. */
493
+ mode?: MetadataReadMode;
494
+ /**
495
+ * `async` only: receives the refreshed result of a cached result that was
496
+ * returned, when the two differ.
497
+ */
498
+ onUpdate?: (result: T) => void;
499
+ /** `async` only: receives the error of a failed background refresh. */
500
+ onError?: (error: unknown) => void;
501
+ /** Also cancels the background refresh; no callback runs once it has aborted. */
502
+ signal?: AbortSignal;
503
+ }
504
+ interface ListResult {
505
+ path: string;
506
+ /** Directories first, then by name. */
507
+ entries: MountraFileEntry[];
508
+ source: MetadataSource;
509
+ /**
510
+ * When the request that returned this result was sent. A cached result
511
+ * also reflects writes made through this client since then.
512
+ */
513
+ fetchedAt: number;
514
+ }
515
+ interface TreeResult {
516
+ path: string;
517
+ root: MountraFileTreeNode;
518
+ source: MetadataSource;
519
+ /** See `ListResult.fetchedAt`. */
520
+ fetchedAt: number;
521
+ }
522
+ type ListOptions = MetadataReadOptions<ListResult>;
523
+ type TreeOptions = MetadataReadOptions<TreeResult>;
524
+ interface MkdirOptions extends WorkspaceSelector {
525
+ /** The directory to create. Its parent must exist. */
526
+ path: string;
527
+ signal?: AbortSignal;
528
+ }
529
+ interface RenameOptions extends WorkspaceSelector {
530
+ fromPath: string;
531
+ /** The new name within the same directory. */
532
+ toName: string;
533
+ signal?: AbortSignal;
534
+ }
535
+ interface MoveOptions extends WorkspaceSelector {
536
+ fromPath: string;
537
+ /** The complete destination path, which must not exist yet. */
538
+ toPath: string;
539
+ signal?: AbortSignal;
540
+ }
541
+ /** Copies one file; Mountra does not copy directories. */
542
+ type CopyOptions = MoveOptions;
543
+ interface DeleteOptions extends WorkspaceSelector {
544
+ /** A file, or an empty directory. */
545
+ path: string;
546
+ signal?: AbortSignal;
547
+ }
548
+ interface FileOperationResult {
549
+ /** The path of the created, renamed, moved, or copied entry. */
550
+ path: string;
551
+ ino: number;
552
+ }
553
+
200
554
  type ChunkMethod = "none" | "fix";
201
555
  type WorkspaceId = number | string;
202
556
  declare const JUMBO_CHUNK_THRESHOLD_BYTES: number;
@@ -225,10 +579,25 @@ interface MountraClientOptions extends WorkspaceSelector {
225
579
  jumboPartSize?: number;
226
580
  /** IndexedDB-backed download checkpoint store. */
227
581
  downloadCheckpointStore?: DownloadCheckpointStore;
582
+ /**
583
+ * Cache downloaded chunks locally, per workspace, in IndexedDB. Disabled
584
+ * unless set; pass `{}` for the defaults.
585
+ */
586
+ downloadCache?: DownloadCacheOptions;
587
+ /**
588
+ * Cache `list` and `tree` results locally, per workspace, in IndexedDB, so
589
+ * reads with `mode: "async"` return at once. Disabled unless set; pass `{}`
590
+ * for the defaults.
591
+ */
592
+ metadataCache?: MetadataCacheOptions;
228
593
  }
229
594
  interface UploadFileOptions extends WorkspaceSelector {
230
595
  path: string;
231
- /** Number of logical chunks. Defaults to 1. */
596
+ /**
597
+ * Maximum number of fixed-size chunks. Defaults to 1. Each chunk is
598
+ * `ceil(size / chunkCount)` bytes except the last, so an uneven split may
599
+ * produce fewer chunks.
600
+ */
232
601
  chunkCount?: number;
233
602
  contentType?: string;
234
603
  nameConflictStrategy?: "overwrite" | "keep_both";
@@ -236,10 +605,17 @@ interface UploadFileOptions extends WorkspaceSelector {
236
605
  onProgress?: (progress: MountraProgress) => void;
237
606
  /** Persist this serializable context before the first chunk is uploaded. */
238
607
  onSessionPrepared?: (context: UploadSessionContext) => void | Promise<void>;
608
+ /**
609
+ * With the client's `downloadCache`, an uploaded file is cached by default so
610
+ * downloading it needs no network. `no-store` only invalidates its old entry.
611
+ */
612
+ cache?: "default" | "no-store";
239
613
  }
240
614
  interface UploadResumeOptions extends WorkspaceSelector {
241
615
  signal?: AbortSignal;
242
616
  onProgress?: (progress: MountraProgress) => void;
617
+ /** See `UploadFileOptions.cache`. */
618
+ cache?: "default" | "no-store";
243
619
  }
244
620
  interface MountraProgress {
245
621
  phase: "uploading" | "finishing";
@@ -426,16 +802,6 @@ interface PreparedUpload {
426
802
  contentHash: string;
427
803
  context: UploadSessionContext;
428
804
  }
429
- declare class MountraApiError extends Error {
430
- readonly status: number;
431
- readonly code?: string;
432
- readonly body?: unknown;
433
- constructor(message: string, input: {
434
- status: number;
435
- code?: string;
436
- body?: unknown;
437
- });
438
- }
439
805
  declare class InMemoryJumboChunkCheckpointStore implements JumboChunkCheckpointStore {
440
806
  private readonly records;
441
807
  load(key: string): Promise<JumboChunkCheckpoint | null>;
@@ -485,6 +851,7 @@ declare class MountraClient {
485
851
  private readonly jumboChunkCheckpointStore;
486
852
  private readonly jumboPartSize;
487
853
  private readonly downloader;
854
+ private readonly metadata;
488
855
  constructor(options: MountraClientOptions);
489
856
  exportFile(options: ExportFileOptions): Promise<ExportFileResponse>;
490
857
  downloadFile(options: DownloadFileOptions): Promise<DownloadResult>;
@@ -492,6 +859,20 @@ declare class MountraClient {
492
859
  resumeDownload(downloadKey: string, options?: DownloadResumeOptions): Promise<DownloadResult>;
493
860
  listResumableDownloads(): Promise<DownloadCheckpoint[]>;
494
861
  clearDownloadCheckpoint(downloadKey: string): Promise<void>;
862
+ /** Clear the download cache of one workspace, or of every workspace when none is given. */
863
+ clearDownloadCache(selector?: WorkspaceSelector): Promise<void>;
864
+ getDownloadCacheUsage(selector?: WorkspaceSelector): Promise<DownloadCacheUsage>;
865
+ /** List the entries of a directory. See `MetadataReadMode` for how `mode` uses the metadata cache. */
866
+ list(options?: ListOptions): Promise<ListResult>;
867
+ /** Return a directory with its complete subtree. See `MetadataReadMode` for how `mode` uses the metadata cache. */
868
+ tree(options?: TreeOptions): Promise<TreeResult>;
869
+ mkdir(options: MkdirOptions): Promise<FileOperationResult>;
870
+ rename(options: RenameOptions): Promise<FileOperationResult>;
871
+ move(options: MoveOptions): Promise<FileOperationResult>;
872
+ copy(options: CopyOptions): Promise<FileOperationResult>;
873
+ delete(options: DeleteOptions): Promise<void>;
874
+ /** Clear the metadata cache of one workspace, or of every workspace when none is given. */
875
+ clearMetadataCache(selector?: WorkspaceSelector): Promise<void>;
495
876
  /** Create a stable resource object for one file in this or another workspace. */
496
877
  file(locator: MountraFileLocator): MountraFile;
497
878
  prepareUpload(file: Blob, options: UploadFileOptions): Promise<PreparedUpload>;
@@ -511,9 +892,23 @@ declare class MountraClient {
511
892
  private isCompatibleJumboCheckpoint;
512
893
  private assertUploadContext;
513
894
  finishUpload(uploadId: string, selector?: WorkspaceSelector): Promise<UploadResult>;
895
+ /** Same workspace resolution as `getWorkspaceBody`, so the cache key matches what Mountra used. */
896
+ private cacheWorkspace;
514
897
  private endpoint;
515
898
  private requestJson;
516
899
  }
517
900
  declare function createMountraClient(options: MountraClientOptions): MountraClient;
518
901
 
519
- export { type AccessToken, type ChunkMethod, DEFAULT_S3_MULTIPART_PART_SIZE_BYTES, type DownloadCheckpoint, type DownloadCheckpointChunk, type DownloadCheckpointRequest, type DownloadCheckpointStore, type DownloadFileOptions, DownloadHttpError, type DownloadProgress, type DownloadResult, type DownloadResumeOptions, type ExportFileChunk, type ExportFileOptions, type ExportFileResponse, type FileChunk, type FileSystemFileHandleLike, type FileSystemWritableFileStreamLike, type FinishUploadResponse, InMemoryDownloadCheckpointStore, InMemoryJumboChunkCheckpointStore, IndexedDBDownloadCheckpointStore, JUMBO_CHUNK_THRESHOLD_BYTES, type JumboChunkCheckpoint, type JumboChunkCheckpointStore, type JumboChunkCompleteInput, type JumboChunkCreateInput, type JumboChunkUploadPartInput, type JumboChunkUploader, LocalStorageJumboChunkCheckpointStore, MAX_S3_MULTIPART_PARTS, MIN_S3_MULTIPART_PART_SIZE_BYTES, MountraApiError, MountraClient, type MountraClientOptions, MountraDownloader, MountraFile, type MountraFileDownloadOptions, type MountraFileExportOptions, type MountraFileLocator, type MountraFileResumeOptions, type MountraProgress, MountraClient as MountraSDK, type NormalizedMountraFileLocator, type PrepareUploadResponse, type PreparedUpload, type S3MultipartClient, type S3MultipartPart, S3MultipartUploader, type UploadFileOptions, type UploadResult, type UploadResumeOptions, type UploadSessionChunkContext, type UploadSessionContext, type UploadStatusChunk, type UploadStatusResponse, type UploadTarget, type WorkspaceId, type WorkspaceSelector, createMountraClient, isJumboChunk, sha256Hex, splitFileIntoChunks };
902
+ /** An HTTP error returned by Mountra, or by a signed upload URL. */
903
+ declare class MountraApiError extends Error {
904
+ readonly status: number;
905
+ readonly code?: string;
906
+ readonly body?: unknown;
907
+ constructor(message: string, input: {
908
+ status: number;
909
+ code?: string;
910
+ body?: unknown;
911
+ });
912
+ }
913
+
914
+ export { type AccessToken, type ChunkMethod, type CopyOptions, DEFAULT_S3_MULTIPART_PART_SIZE_BYTES, type DeleteOptions, type DownloadCacheChunk, type DownloadCacheFile, type DownloadCacheMode, type DownloadCacheOptions, type DownloadCacheStore, type DownloadCacheUsage, type DownloadCheckpoint, type DownloadCheckpointChunk, type DownloadCheckpointRequest, type DownloadCheckpointStore, type DownloadFileOptions, DownloadHttpError, type DownloadProgress, type DownloadResult, type DownloadResumeOptions, type ExportFileChunk, type ExportFileOptions, type ExportFileResponse, type FileChunk, type FileOperationResult, type FileSystemFileHandleLike, type FileSystemWritableFileStreamLike, type FinishUploadResponse, InMemoryDownloadCacheStore, InMemoryDownloadCheckpointStore, InMemoryJumboChunkCheckpointStore, InMemoryMetadataCacheStore, IndexedDBDownloadCacheStore, type IndexedDBDownloadCacheStoreOptions, IndexedDBDownloadCheckpointStore, IndexedDBMetadataCacheStore, type IndexedDBMetadataCacheStoreOptions, JUMBO_CHUNK_THRESHOLD_BYTES, type JumboChunkCheckpoint, type JumboChunkCheckpointStore, type JumboChunkCompleteInput, type JumboChunkCreateInput, type JumboChunkUploadPartInput, type JumboChunkUploader, type ListOptions, type ListResult, LocalStorageJumboChunkCheckpointStore, MAX_S3_MULTIPART_PARTS, MIN_S3_MULTIPART_PART_SIZE_BYTES, type MetadataCacheBatch, type MetadataCacheKind, type MetadataCacheOptions, type MetadataCacheRecord, type MetadataCacheStore, type MetadataListRecord, type MetadataReadMode, type MetadataReadOptions, type MetadataSource, type MetadataTreeRecord, type MkdirOptions, MountraApiError, MountraClient, type MountraClientOptions, MountraDownloader, MountraFile, type MountraFileDownloadOptions, type MountraFileEntry, type MountraFileExportOptions, type MountraFileLocator, type MountraFileResumeOptions, type MountraFileTreeNode, type MountraProgress, MountraClient as MountraSDK, type MoveOptions, type NormalizedMountraFileLocator, type PrepareUploadResponse, type PreparedUpload, type RenameOptions, type S3MultipartClient, type S3MultipartPart, S3MultipartUploader, type TreeOptions, type TreeResult, type UploadFileOptions, type UploadResult, type UploadResumeOptions, type UploadSessionChunkContext, type UploadSessionContext, type UploadStatusChunk, type UploadStatusResponse, type UploadTarget, type WorkspaceId, type WorkspaceSelector, createMountraClient, isJumboChunk, sha256Hex, splitFileIntoChunks };