@gentleduck/upload 0.2.6 → 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/README.md +170 -193
- package/dist/core/index.d.ts +2 -3
- package/dist/core/index.js +1 -1
- package/dist/core-BVgloTiP.js +10 -0
- package/dist/index-DCqyBVcx.d.ts +1441 -0
- package/dist/index-DsZHPmJm.d.ts +225 -0
- package/dist/index-KROXtLQh.d.ts +281 -0
- package/dist/index.d.ts +4 -5
- package/dist/index.js +1 -1
- package/dist/react/index.d.ts +2 -51
- package/dist/react/index.js +1 -1
- package/dist/react-euPrDv24.js +1 -0
- package/dist/strategies/index.d.ts +2 -56
- package/dist/strategies/index.js +1 -1
- package/dist/strategies-CUF0s68j.js +1 -0
- package/package.json +3 -2
- package/src/{__test__ → __tests__}/emitter.test.ts +4 -4
- package/src/{__test__ → __tests__}/fingerprint.test.ts +1 -1
- package/src/{__test__ → __tests__}/guards.test.ts +15 -5
- package/src/__tests__/id.test.ts +67 -0
- package/src/__tests__/mime-sniff.test.ts +142 -0
- package/src/{__test__ → __tests__}/persistence.test.ts +43 -8
- package/src/__tests__/sanitize-filename.test.ts +109 -0
- package/src/__tests__/sleep.test.ts +34 -0
- package/src/__tests__/static-analysis.test.ts +145 -0
- package/src/{__test__ → __tests__}/store-libs.test.ts +57 -3
- package/src/__tests__/transport-fetch.test.ts +108 -0
- package/src/{__test__ → __tests__}/transport.test.ts +5 -5
- package/src/core/__tests__/errors.test.ts +152 -0
- package/src/core/client.ts +3 -0
- package/src/core/contracts/contracts.types.ts +335 -141
- package/src/core/contracts/index.ts +3 -8
- package/src/core/contracts/transport/index.ts +3 -2
- package/src/core/contracts/transport/transport.fetch.ts +203 -0
- package/src/core/contracts/transport/transport.libs.ts +7 -8
- package/src/core/contracts/transport/transport.ts +91 -83
- package/src/core/contracts/transport/transport.types.ts +71 -35
- package/src/core/engine/__tests__/config-nan-bypass.test.ts +40 -0
- package/src/core/engine/engine.libs.ts +35 -0
- package/src/core/engine/engine.types.ts +367 -241
- package/src/core/engine/index.ts +3 -8
- package/src/core/engine/reducer.ts +89 -43
- package/src/core/engine/store/handlers/add-file.ts +39 -29
- package/src/core/engine/store/handlers/cancel.ts +13 -8
- package/src/core/engine/store/handlers/clean-up.ts +11 -8
- package/src/core/engine/store/handlers/create-intent.ts +82 -27
- package/src/core/engine/store/handlers/finalize.ts +30 -13
- package/src/core/engine/store/handlers/index.ts +7 -7
- package/src/core/engine/store/handlers/pause.ts +8 -6
- package/src/core/engine/store/handlers/run-upload.ts +49 -34
- package/src/core/engine/store/index.ts +27 -21
- package/src/core/engine/store/store.dispatch.ts +10 -8
- package/src/core/engine/store/store.libs.ts +184 -41
- package/src/core/engine/store/store.runtime.ts +45 -36
- package/src/core/engine/store/store.schedule.ts +27 -21
- package/src/core/engine/store/store.types.ts +177 -227
- package/src/core/engine/validation/__tests__/intent.test.ts +70 -0
- package/src/core/engine/validation/file.ts +7 -3
- package/src/core/engine/validation/index.ts +1 -0
- package/src/core/engine/validation/intent.ts +49 -27
- package/src/core/engine/validation/list.ts +14 -15
- package/src/core/engine/validation/mime.ts +39 -0
- package/src/core/errors.ts +271 -0
- package/src/core/index.ts +28 -5
- package/src/core/persistence/__tests__/deserialize-nan-bypass.test.ts +100 -0
- package/src/core/persistence/__tests__/persistence.test.ts +85 -0
- package/src/core/persistence/adapters.indexeddb.ts +9 -3
- package/src/core/persistence/adapters.local.ts +9 -3
- package/src/core/persistence/adapters.memory.ts +35 -13
- package/src/core/persistence/index.ts +5 -5
- package/src/core/persistence/persistence.ts +73 -60
- package/src/core/persistence/persistence.types.ts +140 -60
- package/src/core/utils/__tests__/guards.test.ts +93 -0
- package/src/core/utils/__tests__/url-safety.test.ts +112 -0
- package/src/core/utils/async.ts +7 -2
- package/src/core/utils/constants.ts +3 -9
- package/src/core/utils/emitter/emitter.ts +7 -24
- package/src/core/utils/emitter/emitter.types.ts +33 -16
- package/src/core/utils/emitter/index.ts +2 -74
- package/src/core/utils/fingerprint.ts +16 -5
- package/src/core/utils/guards.ts +91 -1
- package/src/core/utils/hash/__tests__/sha256.test.ts +61 -0
- package/src/core/utils/hash/index.ts +126 -0
- package/src/core/utils/hash/sha256.ts +179 -0
- package/src/core/utils/id.ts +33 -1
- package/src/core/utils/index.ts +15 -6
- package/src/core/utils/mime-sniff.ts +119 -0
- package/src/core/utils/sanitize-filename.ts +85 -0
- package/src/core/utils/url-safety.ts +156 -0
- package/src/react/__tests__/use-dropzone.test.ts +64 -0
- package/src/react/index.ts +5 -2
- package/src/react/upload-provider.tsx +68 -53
- package/src/react/uploader.types.ts +58 -61
- package/src/react/use-dropzone.tsx +226 -0
- package/src/react/use-uploader.tsx +98 -91
- package/src/strategies/_shared/__tests__/retry.test.ts +120 -0
- package/src/strategies/_shared/retry.ts +79 -0
- package/src/strategies/index.ts +9 -15
- package/src/strategies/multipart/__tests__/multipart.test.ts +229 -0
- package/src/strategies/multipart/index.ts +206 -108
- package/src/strategies/post/__tests__/post-url-safety.test.ts +119 -0
- package/src/strategies/post/index.ts +115 -33
- package/src/strategies/put/__tests__/put.test.ts +132 -0
- package/src/strategies/put/index.ts +139 -0
- package/src/strategies/registry/index.ts +12 -9
- package/src/strategies/tus/__tests__/tus.test.ts +159 -0
- package/src/strategies/tus/index.ts +211 -0
- package/dist/async-DxRWu4le.js +0 -1
- package/dist/core-CMkrP9DX.js +0 -2
- package/dist/index-C38Jmizu.d.ts +0 -1005
- package/dist/strategy.types-gg9ZStRe.d.ts +0 -225
- package/src/__test__/effect-pool.test.ts +0 -5
- package/src/__test__/id.test.ts +0 -14
- package/src/__test__/store-integration.test.ts +0 -5
- package/src/core/client/client.ts +0 -50
- package/src/core/client/client.types.ts +0 -184
- package/src/core/client/config.types.ts +0 -77
- package/src/core/client/index.ts +0 -4
- package/src/core/client/plugins.types.ts +0 -46
- package/src/core/client/retry.types.ts +0 -6
- package/src/core/client/uploadClient.ts +0 -19
- package/src/core/contracts/backendApi.ts +0 -62
- package/src/core/contracts/cursor.types.ts +0 -23
- package/src/core/contracts/errors.types.ts +0 -67
- package/src/core/contracts/fingerprint.types.ts +0 -18
- package/src/core/contracts/intent.types.ts +0 -39
- package/src/core/contracts/result.types.ts +0 -11
- package/src/core/contracts/strategy.types.ts +0 -45
- package/src/core/engine/commands.types.ts +0 -17
- package/src/core/engine/event-map.types.ts +0 -45
- package/src/core/engine/internal-events.types.ts +0 -202
- package/src/core/engine/outcome.types.ts +0 -9
- package/src/core/engine/progress.types.ts +0 -15
- package/src/core/engine/store/handlers.ts +0 -819
- package/src/core/engine/validation.ts +0 -216
- /package/src/{__test__ → __tests__}/transport-libs.test.ts +0 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { O as Contracts, i as Store, n as Engine } from "./index-DCqyBVcx.js";
|
|
2
|
+
import * as React$1 from "react";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
5
|
+
|
|
6
|
+
//#region src/react/uploader.types.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Public typings and namespaces consumed by React hook components.
|
|
9
|
+
* @author wildduck2 <https://github.com/wildduck2>
|
|
10
|
+
*/
|
|
11
|
+
declare namespace Uploader {
|
|
12
|
+
/**
|
|
13
|
+
* Return state payload returned by the `useUploader` hook.
|
|
14
|
+
*
|
|
15
|
+
* @template M - Intent map type
|
|
16
|
+
* @template C - Cursor map type
|
|
17
|
+
* @template P - Purpose string union type
|
|
18
|
+
* @template R - Backend result shape
|
|
19
|
+
*/
|
|
20
|
+
type State<M extends Contracts.Intent.Map, C extends Contracts.Cursor.Map<M>, P extends string, R extends Contracts.Result.Base = Contracts.Result.Base> = Pick<Store.UploadStore<M, C, P, R>, 'dispatch' | 'on' | 'off'> & {
|
|
21
|
+
/** List of all registered upload items currently tracked. */items: Array<Engine.Item<M, C, P, R>>; /** Upload items grouped by phase. */
|
|
22
|
+
byPhase: Record<Engine.Phase, Array<Engine.Item<M, C, P, R>>>; /** Subset of items currently active in the transfer phase. */
|
|
23
|
+
uploading: Array<Engine.Item<M, C, P, R>>; /** Subset of items currently paused. */
|
|
24
|
+
paused: Array<Engine.Item<M, C, P, R>>; /** Subset of items that successfully completed uploading and backend finalization. */
|
|
25
|
+
completed: Array<Engine.Item<M, C, P, R>>; /** Subset of items currently in the error state. */
|
|
26
|
+
failed: Array<Engine.Item<M, C, P, R>>; /** Subset of items validated and waiting to begin uploading. */
|
|
27
|
+
ready: Array<Engine.Item<M, C, P, R>>;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Bound action callbacks returned by context hooks.
|
|
31
|
+
*
|
|
32
|
+
* Houses both the bound dispatchers and the raw underlying store reference.
|
|
33
|
+
*
|
|
34
|
+
* @template M - Intent map type
|
|
35
|
+
* @template C - Cursor map type
|
|
36
|
+
* @template P - Purpose string union type
|
|
37
|
+
* @template R - Backend result shape
|
|
38
|
+
*/
|
|
39
|
+
type IActions<M extends Contracts.Intent.Map, C extends Contracts.Cursor.Map<M>, P extends string, R extends Contracts.Result.Base = Contracts.Result.Base> = Pick<Store.UploadStore<M, C, P, R>, 'dispatch' | 'on'> & {
|
|
40
|
+
/** The raw upload store instance. */store: Store.UploadStore<M, C, P, R>;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Props for the `<UploadProvider>` component.
|
|
44
|
+
*/
|
|
45
|
+
interface ProviderProps<M extends Contracts.Intent.Map, C extends Contracts.Cursor.Map<M>, P extends string, R extends Contracts.Result.Base = Contracts.Result.Base> {
|
|
46
|
+
/** The upload store instance to distribute. */
|
|
47
|
+
store: Store.UploadStore<M, C, P, R>;
|
|
48
|
+
/** React child elements. */
|
|
49
|
+
children: React.ReactNode;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region src/react/upload-provider.d.ts
|
|
54
|
+
/**
|
|
55
|
+
* Context provider that distributes the upload store across the React component hierarchy.
|
|
56
|
+
*
|
|
57
|
+
* Wrap this provider around the top of your layout to enable child hooks like `useUploader`
|
|
58
|
+
* to access upload status.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```tsx
|
|
62
|
+
* const store = createUploadStore({ ... });
|
|
63
|
+
*
|
|
64
|
+
* function App() {
|
|
65
|
+
* return (
|
|
66
|
+
* <UploadProvider store={store}>
|
|
67
|
+
* <UploadForm />
|
|
68
|
+
* </UploadProvider>
|
|
69
|
+
* );
|
|
70
|
+
* }
|
|
71
|
+
* ```
|
|
72
|
+
* @author wildduck2 <https://github.com/wildduck2>
|
|
73
|
+
*/
|
|
74
|
+
declare function UploadProvider<M extends Contracts.Intent.Map, C extends Contracts.Cursor.Map<M>, P extends string, R extends Contracts.Result.Base = Contracts.Result.Base>({
|
|
75
|
+
store,
|
|
76
|
+
children
|
|
77
|
+
}: Uploader.ProviderProps<M, C, P, R>): react_jsx_runtime0.JSX.Element;
|
|
78
|
+
/**
|
|
79
|
+
* Returns the active upload store instance from context.
|
|
80
|
+
* Throws a runtime exception if called outside an `<UploadProvider>`.
|
|
81
|
+
* @author wildduck2 <https://github.com/wildduck2>
|
|
82
|
+
*/
|
|
83
|
+
declare function useUploadStore<M extends Contracts.Intent.Map, C extends Contracts.Cursor.Map<M>, P extends string, R extends Contracts.Result.Base = Contracts.Result.Base>(): Store.UploadStore<M, C, P, R>;
|
|
84
|
+
/**
|
|
85
|
+
* Runtime type guard: returns `true` when `value` exposes the upload-store
|
|
86
|
+
* surface (`getSnapshot`, `subscribe`, `dispatch`, `on`, `off`, `waitFor`).
|
|
87
|
+
* @author wildduck2 <https://github.com/wildduck2>
|
|
88
|
+
*/
|
|
89
|
+
declare function isUploadStore<M extends Contracts.Intent.Map, C extends Contracts.Cursor.Map<M>, P extends string, R extends Contracts.Result.Base = Contracts.Result.Base>(value: unknown): value is Store.UploadStore<M, C, P, R>;
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/react/use-dropzone.d.ts
|
|
92
|
+
/**
|
|
93
|
+
* Test a file against one token from an `accept` string. A token is a MIME type
|
|
94
|
+
* (`image/png`), a MIME wildcard (`image/*`), or a filename extension (`.pdf`).
|
|
95
|
+
* @internal exported for tests.
|
|
96
|
+
*/
|
|
97
|
+
declare function matchesAcceptToken(file: File, token: string): boolean;
|
|
98
|
+
/**
|
|
99
|
+
* True when `file` satisfies an `accept` list (comma-separated tokens). An empty
|
|
100
|
+
* or absent list accepts everything.
|
|
101
|
+
* @internal exported for tests.
|
|
102
|
+
*/
|
|
103
|
+
declare function fileMatchesAccept(file: File, accept?: string): boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Filter a dropped/selected file list by `accept` and collapse to a single file
|
|
106
|
+
* when `multiple` is false.
|
|
107
|
+
* @internal exported for tests.
|
|
108
|
+
*/
|
|
109
|
+
declare function selectFiles(files: File[], opts: {
|
|
110
|
+
accept?: string | undefined;
|
|
111
|
+
multiple?: boolean | undefined;
|
|
112
|
+
}): File[];
|
|
113
|
+
/** Options for {@link useDropzone}. */
|
|
114
|
+
type UseDropzoneOptions<P extends string> = {
|
|
115
|
+
/** Purpose forwarded to the `addFiles` command. */purpose: P; /** Optional caller metadata forwarded to every backend API call. */
|
|
116
|
+
meta?: Record<string, unknown>;
|
|
117
|
+
/**
|
|
118
|
+
* Comma-separated `accept` list (`"image/*,.pdf"`). Filters dropped files and
|
|
119
|
+
* populates the input's `accept` attribute. Absent = accept everything.
|
|
120
|
+
*/
|
|
121
|
+
accept?: string; /** Allow multiple files. Defaults to `true`. */
|
|
122
|
+
multiple?: boolean; /** Disable all interaction (no drop, no click-to-open). Defaults to `false`. */
|
|
123
|
+
disabled?: boolean; /** Do not open the file dialog when the root is clicked. Defaults to `false`. */
|
|
124
|
+
noClick?: boolean;
|
|
125
|
+
/**
|
|
126
|
+
* Override the default dispatch. When provided, accepted files are handed here
|
|
127
|
+
* instead of being dispatched as `addFiles` to the store.
|
|
128
|
+
*/
|
|
129
|
+
onFiles?: (files: File[]) => void; /** Store instance to dispatch to. Falls back to the `<UploadProvider>` store. */
|
|
130
|
+
store?: Store.UploadStore<Contracts.Intent.Map, Contracts.Cursor.Map<Contracts.Intent.Map>, P, Contracts.Result.Base>;
|
|
131
|
+
};
|
|
132
|
+
/** Return value of {@link useDropzone}. */
|
|
133
|
+
type UseDropzoneReturn = {
|
|
134
|
+
/** True while files are being dragged over the root. */isDragging: boolean; /** Programmatically open the native file picker. */
|
|
135
|
+
open: () => void; /** Ref to attach to the hidden `<input type="file">`. */
|
|
136
|
+
inputRef: React$1.RefObject<HTMLInputElement | null>; /** Spread onto the drop-target element. */
|
|
137
|
+
getRootProps: (extra?: React$1.HTMLAttributes<HTMLElement>) => React$1.HTMLAttributes<HTMLElement>; /** Spread onto the hidden `<input type="file">`. */
|
|
138
|
+
getInputProps: (extra?: React$1.InputHTMLAttributes<HTMLInputElement>) => React$1.InputHTMLAttributes<HTMLInputElement> & {
|
|
139
|
+
ref: React$1.Ref<HTMLInputElement>;
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Headless drag-and-drop / file-picker hook.
|
|
144
|
+
*
|
|
145
|
+
* Wires drop and file-input events to the upload store's `addFiles` command
|
|
146
|
+
* (or a custom `onFiles` handler). Returns prop-getters for the drop target and
|
|
147
|
+
* a hidden file input plus a live `isDragging` flag — styling and markup are
|
|
148
|
+
* entirely yours.
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```tsx
|
|
152
|
+
* function Drop() {
|
|
153
|
+
* const { getRootProps, getInputProps, isDragging, open } = useDropzone({
|
|
154
|
+
* purpose: 'attachment',
|
|
155
|
+
* accept: 'image/*',
|
|
156
|
+
* });
|
|
157
|
+
* return (
|
|
158
|
+
* <div {...getRootProps()} data-active={isDragging}>
|
|
159
|
+
* <input {...getInputProps()} />
|
|
160
|
+
* <button type="button" onClick={open}>Choose files</button>
|
|
161
|
+
* </div>
|
|
162
|
+
* );
|
|
163
|
+
* }
|
|
164
|
+
* ```
|
|
165
|
+
* @author wildduck2 <https://github.com/wildduck2>
|
|
166
|
+
*/
|
|
167
|
+
declare function useDropzone<P extends string>(options: UseDropzoneOptions<P>): UseDropzoneReturn;
|
|
168
|
+
//#endregion
|
|
169
|
+
//#region src/react/use-uploader.d.ts
|
|
170
|
+
/**
|
|
171
|
+
* Hook to consume the upload store state, track files, and interact with the upload engine.
|
|
172
|
+
*
|
|
173
|
+
* Exposes files, categorizes items by status phase (ready, uploading, paused, completed, failed),
|
|
174
|
+
* and registers action dispatchers.
|
|
175
|
+
*
|
|
176
|
+
* Can optionally be passed a specific store instance directly. Otherwise, it will read the store from context.
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```tsx
|
|
180
|
+
* function UploadForm() {
|
|
181
|
+
* const { items, uploading, dispatch } = useUploader();
|
|
182
|
+
*
|
|
183
|
+
* const onFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
184
|
+
* if (e.target.files) {
|
|
185
|
+
* dispatch({ type: 'addFiles', files: Array.from(e.target.files), purpose: 'avatar' });
|
|
186
|
+
* }
|
|
187
|
+
* };
|
|
188
|
+
*
|
|
189
|
+
* return (
|
|
190
|
+
* <div>
|
|
191
|
+
* <input type="file" onChange={onFileChange} multiple />
|
|
192
|
+
* <ul>
|
|
193
|
+
* {items.map(item => (
|
|
194
|
+
* <li key={item.localId}>{item.fingerprint.name} - {item.phase}</li>
|
|
195
|
+
* ))}
|
|
196
|
+
* </ul>
|
|
197
|
+
* </div>
|
|
198
|
+
* );
|
|
199
|
+
* }
|
|
200
|
+
* ```
|
|
201
|
+
*
|
|
202
|
+
* @template M - Intent map type
|
|
203
|
+
* @template C - Cursor map type
|
|
204
|
+
* @template P - Purpose string union type
|
|
205
|
+
* @template R - Backend result shape
|
|
206
|
+
* @author wildduck2 <https://github.com/wildduck2>
|
|
207
|
+
*/
|
|
208
|
+
declare function useUploader<M extends Contracts.Intent.Map, C extends Contracts.Cursor.Map<M>, P extends string, R extends Contracts.Result.Base = Contracts.Result.Base>(providedStore?: Store.UploadStore<M, C, P, R> | undefined): Uploader.State<M, C, P, R>;
|
|
209
|
+
/**
|
|
210
|
+
* Returns the store's imperative actions (dispatch, event bindings) along with a direct
|
|
211
|
+
* reference to the store instance. Does not trigger React re-renders on upload progress or state changes.
|
|
212
|
+
*
|
|
213
|
+
* Use this when you only need to trigger commands or subscribe to events without binding UI lists.
|
|
214
|
+
* @author wildduck2 <https://github.com/wildduck2>
|
|
215
|
+
*/
|
|
216
|
+
declare function useUploaderActions<M extends Contracts.Intent.Map, C extends Contracts.Cursor.Map<M>, P extends string, R extends Contracts.Result.Base = Contracts.Result.Base>(): Uploader.IActions<M, C, P, R>;
|
|
217
|
+
/**
|
|
218
|
+
* Creates a bound `useUploader` hook pre-configured for a specific store instance.
|
|
219
|
+
*
|
|
220
|
+
* Useful for building static multi-uploader widgets or context-free setups.
|
|
221
|
+
* @author wildduck2 <https://github.com/wildduck2>
|
|
222
|
+
*/
|
|
223
|
+
declare function createUploadFactory<M extends Contracts.Intent.Map, C extends Contracts.Cursor.Map<M>, P extends string, R extends Contracts.Result.Base = Contracts.Result.Base>(store: Store.UploadStore<M, C, P, R>): () => Uploader.State<M, C, P, R>;
|
|
224
|
+
//#endregion
|
|
225
|
+
export { UseDropzoneReturn as a, selectFiles as c, isUploadStore as d, useUploadStore as f, UseDropzoneOptions as i, useDropzone as l, useUploader as n, fileMatchesAccept as o, Uploader as p, useUploaderActions as r, matchesAcceptToken as s, createUploadFactory as t, UploadProvider as u };
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { O as Contracts } from "./index-DCqyBVcx.js";
|
|
2
|
+
|
|
3
|
+
//#region src/strategies/multipart/index.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Namespace containing types and interfaces specific to the S3/MinIO multipart upload strategy.
|
|
6
|
+
* @author wildduck2 <https://github.com/wildduck2>
|
|
7
|
+
*/
|
|
8
|
+
declare namespace MultipartStrategy {
|
|
9
|
+
/**
|
|
10
|
+
* Configuration options for the multipart upload strategy.
|
|
11
|
+
*/
|
|
12
|
+
type Config = {
|
|
13
|
+
/** Maximum concurrent HTTP PUT part uploads. Defaults to 4. */maxPartConcurrency?: number;
|
|
14
|
+
/**
|
|
15
|
+
* Optional case-insensitive list of trusted hosts (with optional port, e.g. `upload.example.com`).
|
|
16
|
+
* When specified, every signed part URL must match one of the listed hosts.
|
|
17
|
+
*/
|
|
18
|
+
allowedHosts?: string[];
|
|
19
|
+
/**
|
|
20
|
+
* When `true`, allows private network IP addresses (loopback, link-local, RFC1918) in signed part URLs.
|
|
21
|
+
* Defaults to `false`.
|
|
22
|
+
*/
|
|
23
|
+
allowPrivateHosts?: boolean;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Intent payload detailing part sizing and active upload session IDs returned by backends.
|
|
27
|
+
*/
|
|
28
|
+
type Intent = {
|
|
29
|
+
/** Discriminant matching strategy configuration registry keys. */strategy: 'multipart'; /** Unique database identifier for the file resource. */
|
|
30
|
+
fileId: string; /** Active multipart session ID returned by S3/GCS. */
|
|
31
|
+
uploadId: string; /** Chunk size in bytes for each part slice (typically 5MB minimum). */
|
|
32
|
+
partSize: number; /** Total count of parts predicted for this file size. */
|
|
33
|
+
partCount: number; /** Optional array of pre-generated URLs and headers for each part (if signed up front). */
|
|
34
|
+
parts?: Array<{
|
|
35
|
+
partNumber: number;
|
|
36
|
+
url: string;
|
|
37
|
+
headers?: Record<string, string>;
|
|
38
|
+
}>;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Persisted resume state for multipart strategy uploads.
|
|
42
|
+
*/
|
|
43
|
+
type Cursor = {
|
|
44
|
+
/** List of completed parts. */done: Array<{
|
|
45
|
+
partNumber: number;
|
|
46
|
+
etag: string;
|
|
47
|
+
size: number;
|
|
48
|
+
}>;
|
|
49
|
+
/**
|
|
50
|
+
* True if the backend assembled the parts.
|
|
51
|
+
* Prevents repeating completeMultipart calls on subsequent resume attempts.
|
|
52
|
+
*/
|
|
53
|
+
completed?: true;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* S3/GCS-compatible Resumable Multipart Upload Strategy.
|
|
58
|
+
*
|
|
59
|
+
* Slices files into chunks, uploads them concurrently using S3 PUT requests,
|
|
60
|
+
* and completes the upload on the backend once all chunks are transferred.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```ts
|
|
64
|
+
* const registry = createStrategyRegistry([
|
|
65
|
+
* multipartStrategy({ maxPartConcurrency: 4 })
|
|
66
|
+
* ]);
|
|
67
|
+
* ```
|
|
68
|
+
* @author wildduck2 <https://github.com/wildduck2>
|
|
69
|
+
*/
|
|
70
|
+
declare function multipartStrategy<M extends Contracts.Intent.Map & {
|
|
71
|
+
multipart: MultipartStrategy.Intent;
|
|
72
|
+
}, C extends Contracts.Cursor.Map<M> & {
|
|
73
|
+
multipart?: MultipartStrategy.Cursor;
|
|
74
|
+
}, P extends string = string, R extends Contracts.Result.Base = Contracts.Result.Base>(opts?: MultipartStrategy.Config): Contracts.Strategy.Me<M, C, P, R, 'multipart'>;
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region src/strategies/post/index.d.ts
|
|
77
|
+
/**
|
|
78
|
+
* Types for the presigned HTTP POST upload strategy.
|
|
79
|
+
* @author wildduck2 <https://github.com/wildduck2>
|
|
80
|
+
*/
|
|
81
|
+
declare namespace PostStrategy {
|
|
82
|
+
/**
|
|
83
|
+
* Presigned HTTP POST strategy configuration options.
|
|
84
|
+
*/
|
|
85
|
+
type Config = {
|
|
86
|
+
/**
|
|
87
|
+
* Case-insensitive allow-list of host names (with optional port). When
|
|
88
|
+
* set, the presigned POST URL must match a listed host or it is rejected.
|
|
89
|
+
*/
|
|
90
|
+
allowedHosts?: string[];
|
|
91
|
+
/**
|
|
92
|
+
* When `true`, allow private-network IP literals in the POST URL.
|
|
93
|
+
* Defaults to `false`.
|
|
94
|
+
*/
|
|
95
|
+
allowPrivateHosts?: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Retries after the first attempt for transient network failures.
|
|
98
|
+
* Defaults to the shared retry default (3).
|
|
99
|
+
*/
|
|
100
|
+
maxRetries?: number;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Presigned HTTP POST intent payload mapping parameters returned by backend endpoints.
|
|
104
|
+
*/
|
|
105
|
+
type Intent = {
|
|
106
|
+
/** Discriminant identifier matching strategy configuration registry keys. */strategy: 'post'; /** Unique database identifier for the file resource. */
|
|
107
|
+
fileId: string; /** Presigned POST action destination URL (e.g. presigned S3/GCS bucket location). */
|
|
108
|
+
url: string; /** Key/value pair list representing form properties (e.g. AWS credential fields, policies). */
|
|
109
|
+
fields: Record<string, string>; /** Optional epoch string indicating when the pre-signed credentials lapse. */
|
|
110
|
+
expiresAt?: string;
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Direct strategy cursor state representing that no resumable bytes exist.
|
|
114
|
+
*/
|
|
115
|
+
type Cursor = Record<string, never>;
|
|
116
|
+
}
|
|
117
|
+
/** Convenience alias for {@link PostStrategy.Intent}. */
|
|
118
|
+
type PostIntent = PostStrategy.Intent;
|
|
119
|
+
/**
|
|
120
|
+
* Presigned HTTP POST form strategy.
|
|
121
|
+
*
|
|
122
|
+
* Sends the entire file along with backend policy fields as a single
|
|
123
|
+
* `multipart/form-data` request body. Does not support resumability.
|
|
124
|
+
*
|
|
125
|
+
* Security: the presigned URL is backend-supplied and flows straight to the
|
|
126
|
+
* transport, so a compromised backend or MITM could return a `file:`,
|
|
127
|
+
* `javascript:`, or private-network URL. Every URL is checked with
|
|
128
|
+
* {@link validateUploadUrl}; set {@link PostStrategy.Config.allowedHosts} to
|
|
129
|
+
* lock it to known hosts, or leave `allowPrivateHosts` at its default `false`
|
|
130
|
+
* to block loopback/private addresses.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```ts
|
|
134
|
+
* const strategies = createStrategyRegistry([
|
|
135
|
+
* PostStrategy({ allowedHosts: ['uploads.example.com'] }),
|
|
136
|
+
* MultipartStrategy()
|
|
137
|
+
* ]);
|
|
138
|
+
* ```
|
|
139
|
+
* @author wildduck2 <https://github.com/wildduck2>
|
|
140
|
+
*/
|
|
141
|
+
declare function PostStrategy<M extends Contracts.Intent.Map, C extends Contracts.Cursor.Map<M>, P extends string, R extends Contracts.Result.Base = Contracts.Result.Base>(opts?: PostStrategy.Config): Contracts.Strategy.Me<M, C, P, R, 'post'>;
|
|
142
|
+
//#endregion
|
|
143
|
+
//#region src/strategies/put/index.d.ts
|
|
144
|
+
/**
|
|
145
|
+
* Types for the single-request presigned HTTP PUT upload strategy.
|
|
146
|
+
* @author wildduck2 <https://github.com/wildduck2>
|
|
147
|
+
*/
|
|
148
|
+
declare namespace PutStrategy {
|
|
149
|
+
/**
|
|
150
|
+
* Presigned HTTP PUT strategy configuration options.
|
|
151
|
+
*/
|
|
152
|
+
type Config = {
|
|
153
|
+
/**
|
|
154
|
+
* Case-insensitive allow-list of host names (with optional port). When
|
|
155
|
+
* set, the presigned PUT URL must match a listed host or it is rejected.
|
|
156
|
+
*/
|
|
157
|
+
allowedHosts?: string[];
|
|
158
|
+
/**
|
|
159
|
+
* When `true`, allow private-network IP literals in the PUT URL.
|
|
160
|
+
* Defaults to `false`.
|
|
161
|
+
*/
|
|
162
|
+
allowPrivateHosts?: boolean;
|
|
163
|
+
/**
|
|
164
|
+
* Retries after the first attempt for transient network failures.
|
|
165
|
+
* Defaults to the shared retry default (3).
|
|
166
|
+
*/
|
|
167
|
+
maxRetries?: number;
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* Presigned HTTP PUT intent payload. The whole file body is sent in one
|
|
171
|
+
* request to a backend-signed URL (e.g. S3 `putObject`, GCS signed PUT).
|
|
172
|
+
*/
|
|
173
|
+
type Intent = {
|
|
174
|
+
/** Discriminant identifier matching strategy configuration registry keys. */strategy: 'put'; /** Unique database identifier for the file resource. */
|
|
175
|
+
fileId: string; /** Presigned PUT destination URL. */
|
|
176
|
+
url: string; /** Optional request headers required by the signature (e.g. `Content-Type`). */
|
|
177
|
+
headers?: Record<string, string>; /** Optional epoch string indicating when the pre-signed credentials lapse. */
|
|
178
|
+
expiresAt?: string;
|
|
179
|
+
};
|
|
180
|
+
/**
|
|
181
|
+
* Direct strategy cursor state representing that no resumable bytes exist.
|
|
182
|
+
*/
|
|
183
|
+
type Cursor = Record<string, never>;
|
|
184
|
+
}
|
|
185
|
+
/** Convenience alias for {@link PutStrategy.Intent}. */
|
|
186
|
+
type PutIntent = PutStrategy.Intent;
|
|
187
|
+
/**
|
|
188
|
+
* Presigned single-request HTTP PUT strategy.
|
|
189
|
+
*
|
|
190
|
+
* Sends the entire file as the request body to a backend-signed URL in one PUT.
|
|
191
|
+
* The most common direct-to-storage pattern (S3 `putObject`, GCS/Azure signed
|
|
192
|
+
* PUT). Not resumable — use {@link multipartStrategy} or the tus strategy for
|
|
193
|
+
* resumable transfers.
|
|
194
|
+
*
|
|
195
|
+
* Security: the presigned URL is backend-supplied and flows straight to the
|
|
196
|
+
* transport, so a compromised backend or MITM could return a `file:`,
|
|
197
|
+
* `javascript:`, or private-network URL. Every URL is checked with
|
|
198
|
+
* {@link validateUploadUrl}; set {@link PutStrategy.Config.allowedHosts} to
|
|
199
|
+
* lock it to known hosts, or leave `allowPrivateHosts` at its default `false`
|
|
200
|
+
* to block loopback/private addresses.
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* ```ts
|
|
204
|
+
* const strategies = createStrategyRegistry([
|
|
205
|
+
* PutStrategy({ allowedHosts: ['uploads.example.com'] }),
|
|
206
|
+
* multipartStrategy(),
|
|
207
|
+
* ]);
|
|
208
|
+
* ```
|
|
209
|
+
* @author wildduck2 <https://github.com/wildduck2>
|
|
210
|
+
*/
|
|
211
|
+
declare function PutStrategy<M extends Contracts.Intent.Map, C extends Contracts.Cursor.Map<M>, P extends string, R extends Contracts.Result.Base = Contracts.Result.Base>(opts?: PutStrategy.Config): Contracts.Strategy.Me<M, C, P, R, 'put'>;
|
|
212
|
+
//#endregion
|
|
213
|
+
//#region src/strategies/registry/index.d.ts
|
|
214
|
+
/**
|
|
215
|
+
* Create an empty strategy registry. Register upload strategies with `set`, then
|
|
216
|
+
* resolve them by id with `get` / `has`.
|
|
217
|
+
* @author wildduck2 <https://github.com/wildduck2>
|
|
218
|
+
*/
|
|
219
|
+
declare function createStrategyRegistry<M extends Contracts.Intent.Map, C extends Contracts.Cursor.Map<M>, P extends string, R extends Contracts.Result.Base = Contracts.Result.Base>(): Contracts.Strategy.Registry<M, C, P, R>;
|
|
220
|
+
//#endregion
|
|
221
|
+
//#region src/strategies/tus/index.d.ts
|
|
222
|
+
/**
|
|
223
|
+
* Types for the tus resumable upload strategy.
|
|
224
|
+
* @author wildduck2 <https://github.com/wildduck2>
|
|
225
|
+
*/
|
|
226
|
+
declare namespace TusStrategy {
|
|
227
|
+
/**
|
|
228
|
+
* Configuration options for the tus strategy.
|
|
229
|
+
*/
|
|
230
|
+
type Config = {
|
|
231
|
+
/** PATCH chunk size in bytes. Overridden by `intent.chunkSize`. Defaults to 8 MiB. */chunkSize?: number;
|
|
232
|
+
/**
|
|
233
|
+
* Case-insensitive allow-list of host names (with optional port). When set,
|
|
234
|
+
* the tus upload URL must match a listed host or it is rejected.
|
|
235
|
+
*/
|
|
236
|
+
allowedHosts?: string[];
|
|
237
|
+
/**
|
|
238
|
+
* When `true`, allow private-network IP literals in the tus URL.
|
|
239
|
+
* Defaults to `false`.
|
|
240
|
+
*/
|
|
241
|
+
allowPrivateHosts?: boolean; /** Retries after the first attempt for transient PATCH/HEAD failures. Defaults to 3. */
|
|
242
|
+
maxRetries?: number;
|
|
243
|
+
};
|
|
244
|
+
/**
|
|
245
|
+
* tus intent payload. The backend has already created the upload; `url` is the
|
|
246
|
+
* ready upload resource to PATCH against.
|
|
247
|
+
*/
|
|
248
|
+
type Intent = {
|
|
249
|
+
/** Discriminant matching strategy configuration registry keys. */strategy: 'tus'; /** Unique database identifier for the file resource. */
|
|
250
|
+
fileId: string; /** Ready tus upload URL (backend-created via the creation extension). */
|
|
251
|
+
url: string; /** Optional per-upload chunk size override in bytes. */
|
|
252
|
+
chunkSize?: number; /** Optional extra headers to send on every request (e.g. auth). */
|
|
253
|
+
headers?: Record<string, string>;
|
|
254
|
+
};
|
|
255
|
+
/**
|
|
256
|
+
* Persisted resume state: the last acknowledged upload offset in bytes.
|
|
257
|
+
*/
|
|
258
|
+
type Cursor = {
|
|
259
|
+
/** Byte offset already accepted by the server. */offset: number;
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
/** Convenience alias for {@link TusStrategy.Intent}. */
|
|
263
|
+
type TusIntent = TusStrategy.Intent;
|
|
264
|
+
/**
|
|
265
|
+
* tus resumable upload strategy (creation-less).
|
|
266
|
+
*
|
|
267
|
+
* @example
|
|
268
|
+
* ```ts
|
|
269
|
+
* const registry = createStrategyRegistry([
|
|
270
|
+
* TusStrategy({ allowedHosts: ['tus.example.com'], chunkSize: 8 * 1024 * 1024 }),
|
|
271
|
+
* ]);
|
|
272
|
+
* ```
|
|
273
|
+
* @author wildduck2 <https://github.com/wildduck2>
|
|
274
|
+
*/
|
|
275
|
+
declare function TusStrategy<M extends Contracts.Intent.Map & {
|
|
276
|
+
tus: TusStrategy.Intent;
|
|
277
|
+
}, C extends Contracts.Cursor.Map<M> & {
|
|
278
|
+
tus?: TusStrategy.Cursor;
|
|
279
|
+
}, P extends string = string, R extends Contracts.Result.Base = Contracts.Result.Base>(opts?: TusStrategy.Config): Contracts.Strategy.Me<M, C, P, R, 'tus'>;
|
|
280
|
+
//#endregion
|
|
281
|
+
export { PutStrategy as a, MultipartStrategy as c, PutIntent as i, multipartStrategy as l, TusStrategy as n, PostIntent as o, createStrategyRegistry as r, PostStrategy as s, TusIntent as t };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
export { AnyCursor, AnyIntent, BuiltInUploadError, CursorMap, DEFAULT_MAX_ATTEMPTS, DEFAULT_MAX_CONCURRENT_UPLOADS, DEFAULT_MAX_ITEMS, DEFAULT_PROGRESS_THROTTLE_MS, DEFAULT_RETRY_DELAY_BASE_MS, DEFAULT_RETRY_DELAY_MAX_MS, DeserializeContext, FileFingerprint, IndexedDBAdapter, InflightUpload, IntentBase, IntentMap, InternalEvent, LocalStorageAdapter, MemoryAdapter, MultipartCursor, MultipartIntent, PersistedSnapshot, PersistedUploadItem, PersistenceAdapter, PersistenceOptions, PickItemsByPhase, PostCursor, PostIntent, PostStrategy, RejectReason, RetryDecision, StoreOptions, StoreRuntime, StrategyCtx, StrategyKey, StrategyRegistry, TypedEmitter, UploadApi, UploadClient, UploadCommand, UploadCompletionKind, UploadConfig, UploadConfigInput, UploadError, UploadErrorBase, UploadEventMap, UploadHooks, UploadItem, UploadOutcome, UploadPhase, UploadPlugin, UploadProgress, UploadProvider, UploadResultBase, UploadState, UploadStore, UploadStrategy, UploadTransport, UploadValidationRules, UploaderActions, WithSignal, computeFingerprint, createReducer, createStrategyRegistry, createTypedEmitter, createUploadClient, createUploadFactory, createUploadStore, createXHRTransport, deserializeSnapshot, fingerprintMatches, generateId, isRecord, multipartStrategy, resolveUploadConfig, serializeSnapshot, sleep, useOptionalUploadStore, useUploadStore, useUploader, useUploaderActions, validateFile, validateFileList, validateIntent };
|
|
1
|
+
import { C as UploadUnknownError, D as Transport, E as createXHRTransport, O as Contracts, S as UploadTimeoutError, T as createFetchTransport, _ as UploadHttpError, a as deserializeSnapshot, b as UploadServerError, c as createMemoryAdapter, d as UploadPersistence, f as UploadAbortError, g as UploadErrorContext, h as UploadError, i as Store, l as LocalStorageAdapter, m as UploadEngineError, n as Engine, o as serializeSnapshot, p as UploadAuthError, r as createUploadStore, s as MemoryAdapter, t as resolveUploadConfig, u as IndexedDBAdapter, v as UploadNetworkError, w as UploadValidationError, x as UploadStrategyMissingError, y as UploadRateLimitError } from "./index-DCqyBVcx.js";
|
|
2
|
+
import { a as UseDropzoneReturn, c as selectFiles, d as isUploadStore, f as useUploadStore, i as UseDropzoneOptions, l as useDropzone, n as useUploader, o as fileMatchesAccept, p as Uploader, r as useUploaderActions, s as matchesAcceptToken, t as createUploadFactory, u as UploadProvider } from "./index-DsZHPmJm.js";
|
|
3
|
+
import { a as PutStrategy, c as MultipartStrategy, i as PutIntent, l as multipartStrategy, n as TusStrategy, o as PostIntent, r as createStrategyRegistry, s as PostStrategy, t as TusIntent } from "./index-KROXtLQh.js";
|
|
4
|
+
export { Contracts, Engine, IndexedDBAdapter, LocalStorageAdapter, MemoryAdapter, MultipartStrategy, PostIntent, PostStrategy, PutIntent, PutStrategy, Store, Transport, TusIntent, TusStrategy, UploadAbortError, UploadAuthError, UploadEngineError, UploadError, UploadErrorContext, UploadHttpError, UploadNetworkError, UploadPersistence, UploadProvider, UploadRateLimitError, UploadServerError, UploadStrategyMissingError, UploadTimeoutError, UploadUnknownError, UploadValidationError, Uploader, UseDropzoneOptions, UseDropzoneReturn, createFetchTransport, createMemoryAdapter, createStrategyRegistry, createUploadFactory, createUploadStore, createXHRTransport, deserializeSnapshot, fileMatchesAccept, isUploadStore, matchesAcceptToken, multipartStrategy, resolveUploadConfig, selectFiles, serializeSnapshot, useDropzone, useUploadStore, useUploader, useUploaderActions };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as e,S as t,_ as n,a as r,b as i,c as a,
|
|
1
|
+
import{C as e,S as t,_ as n,a as r,b as i,c as a,f as o,g as s,h as c,i as l,l as u,m as d,n as f,o as p,p as m,r as h,s as g,t as _,u as v,v as y,x as b,y as x}from"./core-BVgloTiP.js";import{a as S,c as C,i as w,l as T,n as E,o as D,r as O,s as k,t as A,u as j}from"./react-euPrDv24.js";import{a as M,i as N,n as P,r as F,t as I}from"./strategies-CUF0s68j.js";export{_ as Engine,a as IndexedDBAdapter,g as LocalStorageAdapter,r as MemoryAdapter,N as PostStrategy,F as PutStrategy,I as TusStrategy,o as UploadAbortError,m as UploadAuthError,d as UploadEngineError,c as UploadHttpError,s as UploadNetworkError,C as UploadProvider,n as UploadRateLimitError,y as UploadServerError,x as UploadStrategyMissingError,i as UploadTimeoutError,b as UploadUnknownError,t as UploadValidationError,u as createFetchTransport,p as createMemoryAdapter,P as createStrategyRegistry,A as createUploadFactory,f as createUploadStore,v as createXHRTransport,h as deserializeSnapshot,w as fileMatchesAccept,T as isUploadStore,S as matchesAcceptToken,M as multipartStrategy,e as resolveUploadConfig,D as selectFiles,l as serializeSnapshot,k as useDropzone,j as useUploadStore,E as useUploader,O as useUploaderActions};
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,51 +1,2 @@
|
|
|
1
|
-
import { f as
|
|
2
|
-
|
|
3
|
-
import { ReactNode } from "react";
|
|
4
|
-
|
|
5
|
-
//#region src/react/upload-provider.d.ts
|
|
6
|
-
/** Provides an upload store to descendants. */
|
|
7
|
-
declare function UploadProvider<M extends IntentMap, C extends CursorMap<M>, P extends string, R extends UploadResultBase = UploadResultBase>({
|
|
8
|
-
store,
|
|
9
|
-
children
|
|
10
|
-
}: {
|
|
11
|
-
store: UploadStore<M, C, P, R>;
|
|
12
|
-
children: ReactNode;
|
|
13
|
-
}): React.JSX.Element;
|
|
14
|
-
/**
|
|
15
|
-
* Read the upload store from context if provided. Returns `null` outside a
|
|
16
|
-
* provider so higher-level hooks can keep their context read unconditional
|
|
17
|
-
* while still accepting an explicit store argument.
|
|
18
|
-
*/
|
|
19
|
-
declare function useOptionalUploadStore<M extends IntentMap, C extends CursorMap<M>, P extends string, R extends UploadResultBase = UploadResultBase>(): UploadStore<M, C, P, R> | null;
|
|
20
|
-
/** Read the upload store from context. Throws when called outside `UploadProvider`. */
|
|
21
|
-
declare function useUploadStore<M extends IntentMap, C extends CursorMap<M>, P extends string, R extends UploadResultBase = UploadResultBase>(): UploadStore<M, C, P, R>;
|
|
22
|
-
//#endregion
|
|
23
|
-
//#region src/react/use-uploader.d.ts
|
|
24
|
-
declare function createUploadFactory<M extends IntentMap, C extends CursorMap<M>, P extends string, R extends UploadResultBase = UploadResultBase>(store: UploadStore<M, C, P, R>): () => Uploader<M, C, P, R>;
|
|
25
|
-
type PickItemsByPhase<Phase extends UploadPhase> = Extract<UploadItem<IntentMap, CursorMap<IntentMap>, string, UploadResultBase>, {
|
|
26
|
-
phase: Phase;
|
|
27
|
-
}>;
|
|
28
|
-
type Uploader<M extends IntentMap, C extends CursorMap<M>, P extends string, R extends UploadResultBase> = {
|
|
29
|
-
items: UploadItem<M, C, P, R>[];
|
|
30
|
-
byPhase: Record<string, UploadItem<M, C, P, R>[]>;
|
|
31
|
-
dispatch: (cmd: UploadCommand<P>) => void;
|
|
32
|
-
on: <K extends keyof UploadEventMap<M, C, P, R> & string>(type: K, cb: (payload: UploadEventMap<M, C, P, R>[K]) => void) => () => void;
|
|
33
|
-
off: <K extends keyof UploadEventMap<M, C, P, R> & string>(type: K, cb: (payload: UploadEventMap<M, C, P, R>[K]) => void) => () => void;
|
|
34
|
-
uploading: UploadItem<M, C, P, R>[];
|
|
35
|
-
paused: UploadItem<M, C, P, R>[];
|
|
36
|
-
completed: UploadItem<M, C, P, R>[];
|
|
37
|
-
failed: UploadItem<M, C, P, R>[];
|
|
38
|
-
ready: UploadItem<M, C, P, R>[];
|
|
39
|
-
};
|
|
40
|
-
/**
|
|
41
|
-
* Imperative action surface. Declared explicitly (not inferred) so generated
|
|
42
|
-
* .d.ts files do not leak internal generic names created by `store.on.bind(store)`.
|
|
43
|
-
*/
|
|
44
|
-
type UploaderActions<M extends IntentMap, C extends CursorMap<M>, P extends string, R extends UploadResultBase = UploadResultBase> = Pick<UploadStore<M, C, P, R>, 'dispatch' | 'on'> & {
|
|
45
|
-
store: UploadStore<M, C, P, R>;
|
|
46
|
-
};
|
|
47
|
-
declare function useUploader<M extends IntentMap, C extends CursorMap<M>, P extends string, R extends UploadResultBase = UploadResultBase>(): Uploader<M, C, P, R>;
|
|
48
|
-
declare function useUploader<M extends IntentMap, C extends CursorMap<M>, P extends string, R extends UploadResultBase = UploadResultBase>(store: UploadStore<M, C, P, R>): Uploader<M, C, P, R>;
|
|
49
|
-
declare function useUploaderActions<M extends IntentMap, C extends CursorMap<M>, P extends string, R extends UploadResultBase = UploadResultBase>(): UploaderActions<M, C, P, R>;
|
|
50
|
-
//#endregion
|
|
51
|
-
export { PickItemsByPhase, UploadProvider, UploaderActions, createUploadFactory, useOptionalUploadStore, useUploadStore, useUploader, useUploaderActions };
|
|
1
|
+
import { a as UseDropzoneReturn, c as selectFiles, d as isUploadStore, f as useUploadStore, i as UseDropzoneOptions, l as useDropzone, n as useUploader, o as fileMatchesAccept, p as Uploader, r as useUploaderActions, s as matchesAcceptToken, t as createUploadFactory, u as UploadProvider } from "../index-DsZHPmJm.js";
|
|
2
|
+
export { UploadProvider, Uploader, UseDropzoneOptions, UseDropzoneReturn, createUploadFactory, fileMatchesAccept, isUploadStore, matchesAcceptToken, selectFiles, useDropzone, useUploadStore, useUploader, useUploaderActions };
|
package/dist/react/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{a as e,c as t,i as n,l as r,n as i,o as a,r as o,s,t as c,u as l}from"../react-euPrDv24.js";export{t as UploadProvider,c as createUploadFactory,n as fileMatchesAccept,r as isUploadStore,e as matchesAcceptToken,a as selectFiles,s as useDropzone,l as useUploadStore,i as useUploader,o as useUploaderActions};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsxDEV as e}from"react/jsx-dev-runtime";import*as t from"react";import{createContext as n,useCallback as r,useContext as i,useEffect as a,useMemo as o,useRef as s,useState as c,useSyncExternalStore as l}from"react";const u=n(null);function d({store:t,children:n}){return a(()=>()=>{`destroy`in t&&typeof t.destroy==`function`&&t.destroy()},[t]),e(u.Provider,{value:t,children:n},void 0,!1,{fileName:`/home/runner/work/duck-upload/duck-upload/packages/duck-upload/src/react/upload-provider.tsx`,lineNumber:43,columnNumber:10},this)}function f(){let e=i(u);if(!e)throw Error(`useUploadStore must be used within an <UploadProvider>`);return e}function p(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.getSnapshot==`function`&&typeof t.subscribe==`function`&&typeof t.dispatch==`function`&&typeof t.on==`function`&&typeof t.off==`function`&&typeof t.waitFor==`function`}function m(e,t){let n=t.trim().toLowerCase();if(!n)return!1;if(n.startsWith(`.`))return e.name.toLowerCase().endsWith(n);let r=(e.type||``).toLowerCase();return n.endsWith(`/*`)?r.startsWith(`${n.slice(0,-1)}`):r===n}function h(e,t){if(!t)return!0;let n=t.split(`,`).map(e=>e.trim()).filter(Boolean);return n.length===0?!0:n.some(t=>m(e,t))}function g(e,t){let n=e.filter(e=>h(e,t.accept));return t.multiple===!1?n.slice(0,1):n}function _(e){let{purpose:t,meta:n,accept:i,multiple:a=!0,disabled:l=!1,noClick:u=!1,onFiles:d}=e,p=f(),m=e.store??p,h=s(null),[_,v]=c(!1),y=s(0),b=r(e=>{if(!e||e.length===0)return;let r=g(Array.from(e),{accept:i,multiple:a});r.length!==0&&(d?d(r):m.dispatch({type:`addFiles`,files:r,purpose:t,meta:n}))},[i,a,d,m,t,n]),x=r(()=>{l||h.current?.click()},[l]),S=r((e={})=>({...e,onDragEnter:t=>{e.onDragEnter?.(t),!l&&(t.preventDefault(),t.stopPropagation(),y.current+=1,v(!0))},onDragOver:t=>{e.onDragOver?.(t),!l&&(t.preventDefault(),t.stopPropagation())},onDragLeave:t=>{e.onDragLeave?.(t),!l&&(t.preventDefault(),t.stopPropagation(),y.current=Math.max(0,y.current-1),y.current===0&&v(!1))},onDrop:t=>{e.onDrop?.(t),!l&&(t.preventDefault(),t.stopPropagation(),y.current=0,v(!1),b(t.dataTransfer?.files??null))},onClick:t=>{e.onClick?.(t),!(l||u)&&x()}}),[l,u,x,b]),C=r((e={})=>({...e,ref:h,type:`file`,multiple:a,disabled:l,...i?{accept:i}:{},style:{display:`none`,...e.style},onChange:t=>{e.onChange?.(t),b(t.target.files),t.target.value=``}}),[a,l,i,b]);return o(()=>({isDragging:_,open:x,inputRef:h,getRootProps:S,getInputProps:C}),[_,x,S,C])}function v(e){let t=f(),n=e??t;if(!n)throw Error(`useUploader must be used within an <UploadProvider> or passed a store instance directly.`);let r=l(n.subscribe,n.getSnapshot,n.getSnapshot),i=o(()=>Array.from(r.items.values()),[r]),a=o(()=>{let e={validating:[],creating_intent:[],ready:[],queued:[],uploading:[],paused:[],completing:[],completed:[],error:[],canceled:[]};return i.forEach(t=>{let n=t.phase;e[n]||(e[n]=[]),e[n].push(t)}),e},[i]);return{items:i,byPhase:a,dispatch:n.dispatch.bind(n),on:n.on.bind(n),off:n.off.bind(n),uploading:a.uploading||[],paused:a.paused||[],completed:a.completed||[],failed:a.error||[],ready:a.ready||[]}}function y(){let e=f();return{dispatch:t.useMemo(()=>e.dispatch.bind(e),[e]),on:t.useMemo(()=>e.on.bind(e),[e]),store:e}}function b(e){return()=>v(e)}export{m as a,d as c,h as i,p as l,v as n,g as o,y as r,_ as s,b as t,f as u};
|