@mountra/mountra-sdk 0.2.0 → 0.3.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,119 @@
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
+ /** Return the chunk bytes and mark the chunk as most recently used. */
56
+ getChunk(workspace: string, storageKey: string): Promise<Blob | null>;
57
+ /** Store the chunk bytes, then evict least recently used chunks until at most `maxBytes` remain. */
58
+ putChunk(workspace: string, storageKey: string, data: Blob, maxBytes: number): Promise<void>;
59
+ /** Remove every entry, or only the entries of one workspace. */
60
+ clear(workspace?: string): Promise<void>;
61
+ usage(workspace?: string): Promise<DownloadCacheUsage>;
62
+ }
63
+ declare class InMemoryDownloadCacheStore implements DownloadCacheStore {
64
+ private readonly files;
65
+ /** Map iteration order is the LRU order: the first entry is the least recently used. */
66
+ private readonly chunks;
67
+ private bytes;
68
+ getFile(workspace: string, fileKey: string): Promise<DownloadCacheFile | null>;
69
+ putFile(workspace: string, fileKey: string, file: DownloadCacheFile): Promise<void>;
70
+ removeFile(workspace: string, fileKey: string): Promise<void>;
71
+ getChunk(workspace: string, storageKey: string): Promise<Blob | null>;
72
+ putChunk(workspace: string, storageKey: string, data: Blob, maxBytes: number): Promise<void>;
73
+ clear(workspace?: string): Promise<void>;
74
+ usage(workspace?: string): Promise<DownloadCacheUsage>;
75
+ private removeChunk;
76
+ }
77
+ interface IndexedDBDownloadCacheStoreOptions {
78
+ /** Use a separate database, for example one per signed-in user. */
79
+ databaseName?: string;
80
+ }
81
+ declare class IndexedDBDownloadCacheStore implements DownloadCacheStore {
82
+ private readonly databaseName;
83
+ private readonly fallback;
84
+ private databasePromise?;
85
+ constructor(options?: IndexedDBDownloadCacheStoreOptions);
86
+ getFile(workspace: string, fileKey: string): Promise<DownloadCacheFile | null>;
87
+ putFile(workspace: string, fileKey: string, file: DownloadCacheFile): Promise<void>;
88
+ removeFile(workspace: string, fileKey: string): Promise<void>;
89
+ getChunk(workspace: string, storageKey: string): Promise<Blob | null>;
90
+ putChunk(workspace: string, storageKey: string, data: Blob, maxBytes: number): Promise<void>;
91
+ clear(workspace?: string): Promise<void>;
92
+ usage(workspace?: string): Promise<DownloadCacheUsage>;
93
+ private openDatabase;
94
+ }
95
+ /** Cache policy of one client. Cache failures degrade to misses and never fail a download. */
96
+ declare class DownloadCache {
97
+ readonly maxBytes: number;
98
+ readonly maxChunkBytes: number;
99
+ readonly ttlMs: number;
100
+ private readonly store;
101
+ constructor(options: DownloadCacheOptions);
102
+ /** Return a file that has not expired together with all of its chunk bytes. */
103
+ loadFile(workspace: string, fileKey: string): Promise<{
104
+ file: DownloadCacheFile;
105
+ chunks: Map<number, Blob>;
106
+ } | null>;
107
+ readChunk(workspace: string, chunk: DownloadCacheChunk): Promise<Blob | null>;
108
+ canStoreChunk(chunk: DownloadCacheChunk): boolean;
109
+ /** Returns whether the chunk is now cached. */
110
+ storeChunk(workspace: string, chunk: DownloadCacheChunk, data: Blob): Promise<boolean>;
111
+ storeFile(workspace: string, fileKey: string, file: Omit<DownloadCacheFile, "cachedAt" | "expiresAt">): Promise<void>;
112
+ invalidateFiles(workspace: string, fileKeys: string[]): Promise<void>;
113
+ clear(workspace?: string): Promise<void>;
114
+ usage(workspace?: string): Promise<DownloadCacheUsage>;
115
+ }
116
+
1
117
  interface FileSystemWritableFileStreamLike {
2
118
  write(data: Uint8Array | Blob): Promise<void>;
3
119
  seek(position: number): Promise<void>;
@@ -67,6 +183,8 @@ interface DownloadFileOptions extends ExportFileOptions {
67
183
  onProgress?: (progress: DownloadProgress) => void;
68
184
  /** Use a previously selected file handle, primarily for resumeDownload. */
69
185
  fileHandle?: FileSystemFileHandleLike;
186
+ /** How this download uses the client's `downloadCache`. Defaults to `default`. */
187
+ cache?: DownloadCacheMode;
70
188
  }
71
189
  interface DownloadResumeOptions {
72
190
  signal?: AbortSignal;
@@ -75,9 +193,12 @@ interface DownloadResumeOptions {
75
193
  onProgress?: (progress: DownloadProgress) => void;
76
194
  }
77
195
  interface DownloadResult {
78
- export: ExportFileResponse;
196
+ /** Absent when the file was served from the download cache without contacting Mountra. */
197
+ export?: ExportFileResponse;
79
198
  downloadKey: string;
80
199
  downloadedBytes: number;
200
+ /** Bytes served from the download cache instead of the network. */
201
+ cachedBytes: number;
81
202
  resumed: boolean;
82
203
  fileHandle?: FileSystemFileHandleLike;
83
204
  blob?: Blob;
@@ -142,6 +263,7 @@ interface DownloadTransport {
142
263
  readonly clientSelector: WorkspaceSelector;
143
264
  readonly fetchImpl: typeof globalThis.fetch;
144
265
  readonly checkpointStore: DownloadCheckpointStore;
266
+ readonly cache: DownloadCache | null;
145
267
  requestJson(path: string, body: unknown, signal?: AbortSignal): Promise<unknown>;
146
268
  }
147
269
  declare class MountraDownloader {
@@ -153,6 +275,35 @@ declare class MountraDownloader {
153
275
  resumeDownload(downloadKey: string, options?: DownloadResumeOptions): Promise<DownloadResult>;
154
276
  listResumableDownloads(): Promise<DownloadCheckpoint[]>;
155
277
  clearDownloadCheckpoint(downloadKey: string): Promise<void>;
278
+ /** Drop the cached layout of a file that was just written, so the next download sees the new content. */
279
+ invalidateCachedFile(selector: WorkspaceSelector, target: {
280
+ path?: string;
281
+ ino?: number | string;
282
+ }): Promise<void>;
283
+ /**
284
+ * Cache a file this client just uploaded, so downloading it needs no
285
+ * network. Falls back to invalidation when any chunk cannot be cached.
286
+ */
287
+ cacheUploadedFile(selector: WorkspaceSelector, file: {
288
+ path: string;
289
+ ino?: number | string;
290
+ size: number;
291
+ contentType?: string;
292
+ chunks: Array<DownloadCacheChunk & {
293
+ data: Blob;
294
+ }>;
295
+ }, mode?: Exclude<DownloadCacheMode, "no-cache">): Promise<void>;
296
+ private cachedFileScope;
297
+ clearCache(selector?: WorkspaceSelector): Promise<void>;
298
+ cacheUsage(selector?: WorkspaceSelector): Promise<DownloadCacheUsage>;
299
+ private requireCacheWorkspace;
300
+ /** Fall back to the client workspace only when the request names none, as uploads do. */
301
+ private resolveRequest;
302
+ private exportRequest;
303
+ private cacheScope;
304
+ /** A plan that needs no network at all, when the cached layout is fresh and every chunk is cached. */
305
+ private loadCachedPlan;
306
+ private planExport;
156
307
  private pickSaveFile;
157
308
  private ensureWritePermission;
158
309
  private downloadResolved;
@@ -225,10 +376,19 @@ interface MountraClientOptions extends WorkspaceSelector {
225
376
  jumboPartSize?: number;
226
377
  /** IndexedDB-backed download checkpoint store. */
227
378
  downloadCheckpointStore?: DownloadCheckpointStore;
379
+ /**
380
+ * Cache downloaded chunks locally, per workspace, in IndexedDB. Disabled
381
+ * unless set; pass `{}` for the defaults.
382
+ */
383
+ downloadCache?: DownloadCacheOptions;
228
384
  }
229
385
  interface UploadFileOptions extends WorkspaceSelector {
230
386
  path: string;
231
- /** Number of logical chunks. Defaults to 1. */
387
+ /**
388
+ * Maximum number of fixed-size chunks. Defaults to 1. Each chunk is
389
+ * `ceil(size / chunkCount)` bytes except the last, so an uneven split may
390
+ * produce fewer chunks.
391
+ */
232
392
  chunkCount?: number;
233
393
  contentType?: string;
234
394
  nameConflictStrategy?: "overwrite" | "keep_both";
@@ -236,10 +396,17 @@ interface UploadFileOptions extends WorkspaceSelector {
236
396
  onProgress?: (progress: MountraProgress) => void;
237
397
  /** Persist this serializable context before the first chunk is uploaded. */
238
398
  onSessionPrepared?: (context: UploadSessionContext) => void | Promise<void>;
399
+ /**
400
+ * With the client's `downloadCache`, an uploaded file is cached by default so
401
+ * downloading it needs no network. `no-store` only invalidates its old entry.
402
+ */
403
+ cache?: "default" | "no-store";
239
404
  }
240
405
  interface UploadResumeOptions extends WorkspaceSelector {
241
406
  signal?: AbortSignal;
242
407
  onProgress?: (progress: MountraProgress) => void;
408
+ /** See `UploadFileOptions.cache`. */
409
+ cache?: "default" | "no-store";
243
410
  }
244
411
  interface MountraProgress {
245
412
  phase: "uploading" | "finishing";
@@ -492,6 +659,9 @@ declare class MountraClient {
492
659
  resumeDownload(downloadKey: string, options?: DownloadResumeOptions): Promise<DownloadResult>;
493
660
  listResumableDownloads(): Promise<DownloadCheckpoint[]>;
494
661
  clearDownloadCheckpoint(downloadKey: string): Promise<void>;
662
+ /** Clear the download cache of one workspace, or of every workspace when none is given. */
663
+ clearDownloadCache(selector?: WorkspaceSelector): Promise<void>;
664
+ getDownloadCacheUsage(selector?: WorkspaceSelector): Promise<DownloadCacheUsage>;
495
665
  /** Create a stable resource object for one file in this or another workspace. */
496
666
  file(locator: MountraFileLocator): MountraFile;
497
667
  prepareUpload(file: Blob, options: UploadFileOptions): Promise<PreparedUpload>;
@@ -511,9 +681,11 @@ declare class MountraClient {
511
681
  private isCompatibleJumboCheckpoint;
512
682
  private assertUploadContext;
513
683
  finishUpload(uploadId: string, selector?: WorkspaceSelector): Promise<UploadResult>;
684
+ /** Same workspace resolution as `getWorkspaceBody`, so the cache key matches what Mountra used. */
685
+ private cacheWorkspace;
514
686
  private endpoint;
515
687
  private requestJson;
516
688
  }
517
689
  declare function createMountraClient(options: MountraClientOptions): MountraClient;
518
690
 
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 };
691
+ export { type AccessToken, type ChunkMethod, DEFAULT_S3_MULTIPART_PART_SIZE_BYTES, 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 FileSystemFileHandleLike, type FileSystemWritableFileStreamLike, type FinishUploadResponse, InMemoryDownloadCacheStore, InMemoryDownloadCheckpointStore, InMemoryJumboChunkCheckpointStore, IndexedDBDownloadCacheStore, type IndexedDBDownloadCacheStoreOptions, 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 };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,119 @@
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
+ /** Return the chunk bytes and mark the chunk as most recently used. */
56
+ getChunk(workspace: string, storageKey: string): Promise<Blob | null>;
57
+ /** Store the chunk bytes, then evict least recently used chunks until at most `maxBytes` remain. */
58
+ putChunk(workspace: string, storageKey: string, data: Blob, maxBytes: number): Promise<void>;
59
+ /** Remove every entry, or only the entries of one workspace. */
60
+ clear(workspace?: string): Promise<void>;
61
+ usage(workspace?: string): Promise<DownloadCacheUsage>;
62
+ }
63
+ declare class InMemoryDownloadCacheStore implements DownloadCacheStore {
64
+ private readonly files;
65
+ /** Map iteration order is the LRU order: the first entry is the least recently used. */
66
+ private readonly chunks;
67
+ private bytes;
68
+ getFile(workspace: string, fileKey: string): Promise<DownloadCacheFile | null>;
69
+ putFile(workspace: string, fileKey: string, file: DownloadCacheFile): Promise<void>;
70
+ removeFile(workspace: string, fileKey: string): Promise<void>;
71
+ getChunk(workspace: string, storageKey: string): Promise<Blob | null>;
72
+ putChunk(workspace: string, storageKey: string, data: Blob, maxBytes: number): Promise<void>;
73
+ clear(workspace?: string): Promise<void>;
74
+ usage(workspace?: string): Promise<DownloadCacheUsage>;
75
+ private removeChunk;
76
+ }
77
+ interface IndexedDBDownloadCacheStoreOptions {
78
+ /** Use a separate database, for example one per signed-in user. */
79
+ databaseName?: string;
80
+ }
81
+ declare class IndexedDBDownloadCacheStore implements DownloadCacheStore {
82
+ private readonly databaseName;
83
+ private readonly fallback;
84
+ private databasePromise?;
85
+ constructor(options?: IndexedDBDownloadCacheStoreOptions);
86
+ getFile(workspace: string, fileKey: string): Promise<DownloadCacheFile | null>;
87
+ putFile(workspace: string, fileKey: string, file: DownloadCacheFile): Promise<void>;
88
+ removeFile(workspace: string, fileKey: string): Promise<void>;
89
+ getChunk(workspace: string, storageKey: string): Promise<Blob | null>;
90
+ putChunk(workspace: string, storageKey: string, data: Blob, maxBytes: number): Promise<void>;
91
+ clear(workspace?: string): Promise<void>;
92
+ usage(workspace?: string): Promise<DownloadCacheUsage>;
93
+ private openDatabase;
94
+ }
95
+ /** Cache policy of one client. Cache failures degrade to misses and never fail a download. */
96
+ declare class DownloadCache {
97
+ readonly maxBytes: number;
98
+ readonly maxChunkBytes: number;
99
+ readonly ttlMs: number;
100
+ private readonly store;
101
+ constructor(options: DownloadCacheOptions);
102
+ /** Return a file that has not expired together with all of its chunk bytes. */
103
+ loadFile(workspace: string, fileKey: string): Promise<{
104
+ file: DownloadCacheFile;
105
+ chunks: Map<number, Blob>;
106
+ } | null>;
107
+ readChunk(workspace: string, chunk: DownloadCacheChunk): Promise<Blob | null>;
108
+ canStoreChunk(chunk: DownloadCacheChunk): boolean;
109
+ /** Returns whether the chunk is now cached. */
110
+ storeChunk(workspace: string, chunk: DownloadCacheChunk, data: Blob): Promise<boolean>;
111
+ storeFile(workspace: string, fileKey: string, file: Omit<DownloadCacheFile, "cachedAt" | "expiresAt">): Promise<void>;
112
+ invalidateFiles(workspace: string, fileKeys: string[]): Promise<void>;
113
+ clear(workspace?: string): Promise<void>;
114
+ usage(workspace?: string): Promise<DownloadCacheUsage>;
115
+ }
116
+
1
117
  interface FileSystemWritableFileStreamLike {
2
118
  write(data: Uint8Array | Blob): Promise<void>;
3
119
  seek(position: number): Promise<void>;
@@ -67,6 +183,8 @@ interface DownloadFileOptions extends ExportFileOptions {
67
183
  onProgress?: (progress: DownloadProgress) => void;
68
184
  /** Use a previously selected file handle, primarily for resumeDownload. */
69
185
  fileHandle?: FileSystemFileHandleLike;
186
+ /** How this download uses the client's `downloadCache`. Defaults to `default`. */
187
+ cache?: DownloadCacheMode;
70
188
  }
71
189
  interface DownloadResumeOptions {
72
190
  signal?: AbortSignal;
@@ -75,9 +193,12 @@ interface DownloadResumeOptions {
75
193
  onProgress?: (progress: DownloadProgress) => void;
76
194
  }
77
195
  interface DownloadResult {
78
- export: ExportFileResponse;
196
+ /** Absent when the file was served from the download cache without contacting Mountra. */
197
+ export?: ExportFileResponse;
79
198
  downloadKey: string;
80
199
  downloadedBytes: number;
200
+ /** Bytes served from the download cache instead of the network. */
201
+ cachedBytes: number;
81
202
  resumed: boolean;
82
203
  fileHandle?: FileSystemFileHandleLike;
83
204
  blob?: Blob;
@@ -142,6 +263,7 @@ interface DownloadTransport {
142
263
  readonly clientSelector: WorkspaceSelector;
143
264
  readonly fetchImpl: typeof globalThis.fetch;
144
265
  readonly checkpointStore: DownloadCheckpointStore;
266
+ readonly cache: DownloadCache | null;
145
267
  requestJson(path: string, body: unknown, signal?: AbortSignal): Promise<unknown>;
146
268
  }
147
269
  declare class MountraDownloader {
@@ -153,6 +275,35 @@ declare class MountraDownloader {
153
275
  resumeDownload(downloadKey: string, options?: DownloadResumeOptions): Promise<DownloadResult>;
154
276
  listResumableDownloads(): Promise<DownloadCheckpoint[]>;
155
277
  clearDownloadCheckpoint(downloadKey: string): Promise<void>;
278
+ /** Drop the cached layout of a file that was just written, so the next download sees the new content. */
279
+ invalidateCachedFile(selector: WorkspaceSelector, target: {
280
+ path?: string;
281
+ ino?: number | string;
282
+ }): Promise<void>;
283
+ /**
284
+ * Cache a file this client just uploaded, so downloading it needs no
285
+ * network. Falls back to invalidation when any chunk cannot be cached.
286
+ */
287
+ cacheUploadedFile(selector: WorkspaceSelector, file: {
288
+ path: string;
289
+ ino?: number | string;
290
+ size: number;
291
+ contentType?: string;
292
+ chunks: Array<DownloadCacheChunk & {
293
+ data: Blob;
294
+ }>;
295
+ }, mode?: Exclude<DownloadCacheMode, "no-cache">): Promise<void>;
296
+ private cachedFileScope;
297
+ clearCache(selector?: WorkspaceSelector): Promise<void>;
298
+ cacheUsage(selector?: WorkspaceSelector): Promise<DownloadCacheUsage>;
299
+ private requireCacheWorkspace;
300
+ /** Fall back to the client workspace only when the request names none, as uploads do. */
301
+ private resolveRequest;
302
+ private exportRequest;
303
+ private cacheScope;
304
+ /** A plan that needs no network at all, when the cached layout is fresh and every chunk is cached. */
305
+ private loadCachedPlan;
306
+ private planExport;
156
307
  private pickSaveFile;
157
308
  private ensureWritePermission;
158
309
  private downloadResolved;
@@ -225,10 +376,19 @@ interface MountraClientOptions extends WorkspaceSelector {
225
376
  jumboPartSize?: number;
226
377
  /** IndexedDB-backed download checkpoint store. */
227
378
  downloadCheckpointStore?: DownloadCheckpointStore;
379
+ /**
380
+ * Cache downloaded chunks locally, per workspace, in IndexedDB. Disabled
381
+ * unless set; pass `{}` for the defaults.
382
+ */
383
+ downloadCache?: DownloadCacheOptions;
228
384
  }
229
385
  interface UploadFileOptions extends WorkspaceSelector {
230
386
  path: string;
231
- /** Number of logical chunks. Defaults to 1. */
387
+ /**
388
+ * Maximum number of fixed-size chunks. Defaults to 1. Each chunk is
389
+ * `ceil(size / chunkCount)` bytes except the last, so an uneven split may
390
+ * produce fewer chunks.
391
+ */
232
392
  chunkCount?: number;
233
393
  contentType?: string;
234
394
  nameConflictStrategy?: "overwrite" | "keep_both";
@@ -236,10 +396,17 @@ interface UploadFileOptions extends WorkspaceSelector {
236
396
  onProgress?: (progress: MountraProgress) => void;
237
397
  /** Persist this serializable context before the first chunk is uploaded. */
238
398
  onSessionPrepared?: (context: UploadSessionContext) => void | Promise<void>;
399
+ /**
400
+ * With the client's `downloadCache`, an uploaded file is cached by default so
401
+ * downloading it needs no network. `no-store` only invalidates its old entry.
402
+ */
403
+ cache?: "default" | "no-store";
239
404
  }
240
405
  interface UploadResumeOptions extends WorkspaceSelector {
241
406
  signal?: AbortSignal;
242
407
  onProgress?: (progress: MountraProgress) => void;
408
+ /** See `UploadFileOptions.cache`. */
409
+ cache?: "default" | "no-store";
243
410
  }
244
411
  interface MountraProgress {
245
412
  phase: "uploading" | "finishing";
@@ -492,6 +659,9 @@ declare class MountraClient {
492
659
  resumeDownload(downloadKey: string, options?: DownloadResumeOptions): Promise<DownloadResult>;
493
660
  listResumableDownloads(): Promise<DownloadCheckpoint[]>;
494
661
  clearDownloadCheckpoint(downloadKey: string): Promise<void>;
662
+ /** Clear the download cache of one workspace, or of every workspace when none is given. */
663
+ clearDownloadCache(selector?: WorkspaceSelector): Promise<void>;
664
+ getDownloadCacheUsage(selector?: WorkspaceSelector): Promise<DownloadCacheUsage>;
495
665
  /** Create a stable resource object for one file in this or another workspace. */
496
666
  file(locator: MountraFileLocator): MountraFile;
497
667
  prepareUpload(file: Blob, options: UploadFileOptions): Promise<PreparedUpload>;
@@ -511,9 +681,11 @@ declare class MountraClient {
511
681
  private isCompatibleJumboCheckpoint;
512
682
  private assertUploadContext;
513
683
  finishUpload(uploadId: string, selector?: WorkspaceSelector): Promise<UploadResult>;
684
+ /** Same workspace resolution as `getWorkspaceBody`, so the cache key matches what Mountra used. */
685
+ private cacheWorkspace;
514
686
  private endpoint;
515
687
  private requestJson;
516
688
  }
517
689
  declare function createMountraClient(options: MountraClientOptions): MountraClient;
518
690
 
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 };
691
+ export { type AccessToken, type ChunkMethod, DEFAULT_S3_MULTIPART_PART_SIZE_BYTES, 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 FileSystemFileHandleLike, type FileSystemWritableFileStreamLike, type FinishUploadResponse, InMemoryDownloadCacheStore, InMemoryDownloadCheckpointStore, InMemoryJumboChunkCheckpointStore, IndexedDBDownloadCacheStore, type IndexedDBDownloadCacheStoreOptions, 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 };