@vryzel/file-next-headless 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.
@@ -0,0 +1,271 @@
1
+ import { TenantId, Result, FileNode, FileSystemError } from '@vryzel/file-next';
2
+ import { FileSystemError as FileSystemError$1 } from '@vryzel/file-next/errors';
3
+
4
+ /** Narrow shape of what the hook needs from the server action. */
5
+ type ListFilesInput = {
6
+ readonly tenantId: TenantId;
7
+ readonly parentId: string | null;
8
+ readonly prefix?: string;
9
+ readonly limit?: number;
10
+ };
11
+ type ListFilesOutput = {
12
+ readonly items: ReadonlyArray<FileNode>;
13
+ };
14
+ /** The injected dependency. Returns the same Result shape the server uses. */
15
+ type ListFilesFn = (input: ListFilesInput) => Promise<Result<ListFilesOutput, FileSystemError>>;
16
+ interface UseFileBrowserOptions {
17
+ /** The list callback (injected; typically wraps a server action). */
18
+ readonly listFiles: ListFilesFn;
19
+ /** Tenant scope — forwarded to every listFiles call. */
20
+ readonly tenantId: TenantId;
21
+ /** Folder to list (null = root). */
22
+ readonly parentId: string | null;
23
+ /** Optional S3 prefix filter. */
24
+ readonly prefix?: string;
25
+ /** Optional cap on items per call. */
26
+ readonly limit?: number;
27
+ /**
28
+ * Auto-fetch on mount (default: false). The spec describes the
29
+ * state machine as `idle → user calls refetch() → loading → ...`,
30
+ * so the hook is imperative by default. Set `true` to fetch as
31
+ * soon as the component mounts (typical for full-page file
32
+ * browsers that want to show data immediately).
33
+ */
34
+ readonly autoFetch?: boolean;
35
+ }
36
+ type UseFileBrowserStatus = "idle" | "loading" | "success" | "error";
37
+ interface UseFileBrowserState {
38
+ readonly status: UseFileBrowserStatus;
39
+ readonly files: ReadonlyArray<FileNode>;
40
+ readonly error: FileSystemError | null;
41
+ }
42
+ interface UseFileBrowserReturn {
43
+ readonly status: UseFileBrowserStatus;
44
+ readonly files: ReadonlyArray<FileNode>;
45
+ readonly error: FileSystemError | null;
46
+ /** Re-run the listFiles call. Safe to call any time; cancels nothing. */
47
+ readonly refetch: () => Promise<void>;
48
+ }
49
+ /**
50
+ * useFileBrowser — list files for a folder via an injected callback.
51
+ *
52
+ * The hook fires the list on mount (unless `autoFetch: false`) and
53
+ * exposes a stable `refetch` to re-run. The state is local: every
54
+ * consumer instance has its own state machine.
55
+ */
56
+ declare function useFileBrowser(options: UseFileBrowserOptions): UseFileBrowserReturn;
57
+
58
+ /** Narrow file shape — the hook doesn't need the full DOM File. */
59
+ interface UploaderFile {
60
+ readonly name: string;
61
+ readonly size: number;
62
+ readonly type: string;
63
+ readonly content: Blob;
64
+ }
65
+ /** Optional post-upload confirm callback. Receives the XHR + the file. */
66
+ type ConfirmUploadFn = (xhr: XMLHttpRequest, file: UploaderFile, meta?: {
67
+ id?: string;
68
+ }) => void;
69
+ interface RequestUploadResult {
70
+ readonly url: string;
71
+ readonly method?: "PUT" | "POST";
72
+ readonly headers?: Record<string, string>;
73
+ readonly id?: string;
74
+ }
75
+ interface UseUploaderOptions {
76
+ /** The presigned URL to PUT the file to. Ignored when `requestUpload` is set. */
77
+ readonly uploadUrl?: string;
78
+ /** Resolve a fresh presigned URL per file (preferred). */
79
+ readonly requestUpload?: (file: UploaderFile) => Promise<RequestUploadResult>;
80
+ /**
81
+ * Optional callback fired once the upload completes successfully.
82
+ * Typically used to trigger a server action that records metadata.
83
+ * NEVER fires if the upload is canceled.
84
+ */
85
+ readonly confirmUpload?: ConfirmUploadFn;
86
+ }
87
+ type UseUploaderStatus = "idle" | "uploading" | "success" | "error" | "aborted";
88
+ interface UseUploaderState {
89
+ readonly status: UseUploaderStatus;
90
+ readonly progress: number;
91
+ readonly error: FileSystemError$1 | null;
92
+ }
93
+ interface UseUploaderReturn {
94
+ readonly status: UseUploaderStatus;
95
+ readonly progress: number;
96
+ readonly error: FileSystemError$1 | null;
97
+ /** Kick off an upload. No-op if an upload is already in flight. */
98
+ readonly upload: (file: UploaderFile) => void;
99
+ /** Abort the in-flight upload. No-op if idle / done. */
100
+ readonly cancel: () => void;
101
+ }
102
+ /**
103
+ * useUploader — upload via XHR with progress + cancel.
104
+ *
105
+ * The hook is intentionally imperative: the consumer calls
106
+ * `upload(file)` to start, and may call `cancel()` to abort.
107
+ * No effects fire automatically (uploads should not happen until
108
+ * the user picks a file).
109
+ */
110
+ declare function useUploader(options: UseUploaderOptions): UseUploaderReturn;
111
+
112
+ interface DeleteFileInput {
113
+ readonly id: string;
114
+ }
115
+ interface DeleteFileOutput {
116
+ readonly id: string;
117
+ }
118
+ interface MoveFileInput {
119
+ readonly id: string;
120
+ readonly newParentId: string;
121
+ }
122
+ interface MoveFileOutput {
123
+ readonly id: string;
124
+ }
125
+ interface CopyFileInput {
126
+ readonly id: string;
127
+ readonly newParentId: string;
128
+ }
129
+ interface CopyFileOutput {
130
+ readonly node: FileNode;
131
+ }
132
+ type DeleteFileFn = (input: DeleteFileInput) => Promise<Result<DeleteFileOutput, FileSystemError>>;
133
+ type MoveFileFn = (input: MoveFileInput) => Promise<Result<MoveFileOutput, FileSystemError>>;
134
+ type CopyFileFn = (input: CopyFileInput) => Promise<Result<CopyFileOutput, FileSystemError>>;
135
+ type RenameFileFn = (id: string, newName: string) => Promise<void>;
136
+ interface UseFileActionsOptions {
137
+ /** The current file list (consumer-owned). */
138
+ readonly files: ReadonlyArray<FileNode>;
139
+ /** The state setter for the file list (consumer-owned). */
140
+ readonly setFiles: (next: ReadonlyArray<FileNode>) => void;
141
+ /** The three server-action callbacks (typically wrappers around RSC actions). */
142
+ readonly actions: {
143
+ readonly deleteFile: DeleteFileFn;
144
+ readonly moveFile: MoveFileFn;
145
+ readonly copyFile: CopyFileFn;
146
+ readonly renameFile: RenameFileFn;
147
+ };
148
+ }
149
+ type UseFileActionsStatus = "idle" | "pending";
150
+ interface UseFileActionsState {
151
+ readonly status: UseFileActionsStatus;
152
+ readonly error: FileSystemError | null;
153
+ }
154
+ interface UseFileActionsReturn {
155
+ readonly status: UseFileActionsStatus;
156
+ readonly isPending: boolean;
157
+ readonly error: FileSystemError | null;
158
+ readonly deleteFile: (id: string) => Promise<void>;
159
+ readonly moveFile: (id: string, newParentId: string) => Promise<void>;
160
+ readonly copyFile: (id: string, newParentId: string) => Promise<void>;
161
+ readonly renameFile: (id: string, newName: string) => Promise<void>;
162
+ }
163
+ /**
164
+ * useFileActions — optimistic mutations with rollback.
165
+ *
166
+ * Each mutator:
167
+ * 1. Snapshots the current `files` reference.
168
+ * 2. Dispatches `START` (isPending = true).
169
+ * 3. Calls `setFiles(optimistic)` immediately.
170
+ * 4. Awaits the action.
171
+ * 5. On `ok: true`, dispatches `SUCCESS` (no further setFiles — the
172
+ * server's response is the new truth; the optimistic value
173
+ * either matches or the consumer reconciles via refresh).
174
+ * 6. On `ok: false`, calls `setFiles(snapshot)` to roll back, then
175
+ * dispatches `ERROR`.
176
+ */
177
+ declare function useFileActions(options: UseFileActionsOptions): UseFileActionsReturn;
178
+
179
+ interface GetDownloadUrlInput {
180
+ readonly key: string;
181
+ }
182
+ interface GetDownloadUrlOutput {
183
+ readonly url: string;
184
+ }
185
+ type GetDownloadUrlFn = (input: GetDownloadUrlInput) => Promise<Result<GetDownloadUrlOutput, FileSystemError>>;
186
+ interface UseFileUrlOptions {
187
+ /** The injected download-URL resolver (wraps a server action). */
188
+ readonly getDownloadUrl: GetDownloadUrlFn;
189
+ /** The object key to resolve a URL for. */
190
+ readonly key: string;
191
+ /**
192
+ * When false, the fetch is skipped (status stays `idle`, url is
193
+ * null). Useful for click-to-load patterns and conditional prefetch.
194
+ * Default: true.
195
+ */
196
+ readonly enabled?: boolean;
197
+ }
198
+ type UseFileUrlStatus = "idle" | "loading" | "success" | "error";
199
+ interface UseFileUrlReturn {
200
+ readonly url: string | null;
201
+ readonly status: UseFileUrlStatus;
202
+ readonly error: FileSystemError | null;
203
+ }
204
+ declare function useFileUrl(options: UseFileUrlOptions): UseFileUrlReturn;
205
+
206
+ interface UseDownloadProgressOptions {
207
+ /** The URL to download from. */
208
+ readonly url: string;
209
+ /**
210
+ * Optional AbortSignal to share cancellation with the consumer's
211
+ * own logic (e.g., the consumer unmounts the component).
212
+ * If provided, the hook's `cancel()` AND this signal both abort.
213
+ */
214
+ readonly externalSignal?: AbortSignal;
215
+ }
216
+ type UseDownloadProgressStatus = "idle" | "loading" | "success" | "error" | "aborted";
217
+ interface UseDownloadProgressState {
218
+ readonly status: UseDownloadProgressStatus;
219
+ readonly progress: number;
220
+ readonly blob: Blob | null;
221
+ readonly error: FileSystemError$1 | null;
222
+ }
223
+ interface UseDownloadProgressReturn {
224
+ readonly status: UseDownloadProgressStatus;
225
+ readonly progress: number;
226
+ readonly blob: Blob | null;
227
+ readonly error: FileSystemError$1 | null;
228
+ readonly cancel: () => void;
229
+ }
230
+ declare function useDownloadProgress(options: UseDownloadProgressOptions): UseDownloadProgressReturn;
231
+
232
+ type ViewMode = "list" | "grid";
233
+ interface UseFileExplorerOptions {
234
+ /** List callback (injected). */
235
+ readonly listFiles: Parameters<typeof useFileBrowser>[0]["listFiles"];
236
+ /** Tenant scope. */
237
+ readonly tenantId: TenantId;
238
+ /** Current folder (null = root). */
239
+ readonly parentId: string | null;
240
+ /** Initial view mode. Default: "list". */
241
+ readonly initialView?: ViewMode;
242
+ /** Auto-fetch on mount. Default: true (the explorer expects data). */
243
+ readonly autoFetch?: boolean;
244
+ /** Optional callback fired when the user picks a file/folder via click or keyboard. */
245
+ readonly onActivate?: (file: FileNode) => void;
246
+ readonly onMove?: (input: {
247
+ itemIds: ReadonlyArray<string>;
248
+ destinationFolderId: string;
249
+ }) => Promise<void> | void;
250
+ }
251
+ interface UseFileExplorerReturn {
252
+ readonly status: ReturnType<typeof useFileBrowser>["status"];
253
+ readonly files: ReadonlyArray<FileNode>;
254
+ readonly error: ReturnType<typeof useFileBrowser>["error"];
255
+ readonly refetch: () => Promise<void>;
256
+ readonly view: ViewMode;
257
+ readonly setView: (v: ViewMode) => void;
258
+ readonly selectedId: string | null;
259
+ readonly setSelected: (id: string | null) => void;
260
+ readonly contextTarget: FileNode | null;
261
+ readonly openContextMenu: (file: FileNode | null) => void;
262
+ readonly draggingId: string | null;
263
+ readonly dropTargetId: string | null;
264
+ readonly beginDrag: (id: string) => void;
265
+ readonly setDropTarget: (id: string | null) => void;
266
+ readonly commitDrop: (destinationFolderId: string) => void;
267
+ readonly endDrag: () => void;
268
+ }
269
+ declare function useFileExplorer(options: UseFileExplorerOptions): UseFileExplorerReturn;
270
+
271
+ export { type ConfirmUploadFn, type CopyFileFn, type CopyFileInput, type CopyFileOutput, type DeleteFileFn, type DeleteFileInput, type DeleteFileOutput, type GetDownloadUrlFn, type GetDownloadUrlInput, type GetDownloadUrlOutput, type ListFilesFn, type ListFilesInput, type ListFilesOutput, type MoveFileFn, type MoveFileInput, type MoveFileOutput, type RequestUploadResult, type UploaderFile, type UseDownloadProgressOptions, type UseDownloadProgressReturn, type UseDownloadProgressState, type UseDownloadProgressStatus, type UseFileActionsOptions, type UseFileActionsReturn, type UseFileActionsState, type UseFileActionsStatus, type UseFileBrowserOptions, type UseFileBrowserReturn, type UseFileBrowserState, type UseFileBrowserStatus, type UseFileExplorerOptions, type UseFileExplorerReturn, type UseFileUrlOptions, type UseFileUrlReturn, type UseFileUrlStatus, type UseUploaderOptions, type UseUploaderReturn, type UseUploaderState, type UseUploaderStatus, type ViewMode, useDownloadProgress, useFileActions, useFileBrowser, useFileExplorer, useFileUrl, useUploader };