@useupup/core 3.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.
Files changed (118) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +8 -0
  3. package/README.md +75 -0
  4. package/dist/browser-SXR426OQ.cjs +10 -0
  5. package/dist/browser-WD6T5ABJ.js +1 -0
  6. package/dist/chunk-2H5ICKFT.cjs +122 -0
  7. package/dist/chunk-6HF3I2JS.cjs +39 -0
  8. package/dist/chunk-6S5DQDQH.js +212 -0
  9. package/dist/chunk-BMQC27OE.cjs +92 -0
  10. package/dist/chunk-BSGQGINR.cjs +219 -0
  11. package/dist/chunk-CPKZ2CXD.cjs +179 -0
  12. package/dist/chunk-DTKDIMKT.cjs +573 -0
  13. package/dist/chunk-DYE5XJ6Z.cjs +2134 -0
  14. package/dist/chunk-E3ZCNOXG.cjs +74 -0
  15. package/dist/chunk-FEQY2WYY.cjs +2377 -0
  16. package/dist/chunk-FMURBCZ7.js +120 -0
  17. package/dist/chunk-FYQQRULL.js +37 -0
  18. package/dist/chunk-GE4LIVXP.js +133 -0
  19. package/dist/chunk-HFR5HZJZ.js +56 -0
  20. package/dist/chunk-I7ULPCA2.js +72 -0
  21. package/dist/chunk-MHYXDLZR.js +569 -0
  22. package/dist/chunk-N2SLHVAW.cjs +61 -0
  23. package/dist/chunk-OOPDEOTM.js +169 -0
  24. package/dist/chunk-PMBR3OUW.js +2359 -0
  25. package/dist/chunk-QK7HZIVY.cjs +144 -0
  26. package/dist/chunk-T2AQHY7V.cjs +59 -0
  27. package/dist/chunk-TRCP5FUR.js +90 -0
  28. package/dist/chunk-U7KL5M2H.cjs +374 -0
  29. package/dist/chunk-UXNPM54W.js +2108 -0
  30. package/dist/chunk-VV6QCQLL.js +365 -0
  31. package/dist/chunk-ZMS2HXLB.js +56 -0
  32. package/dist/context-shapes-123dd3b6.d.cts +207 -0
  33. package/dist/context-shapes-27b24c8f.d.ts +207 -0
  34. package/dist/contracts-pipeline-cf177270.d.cts +78 -0
  35. package/dist/contracts-pipeline-cf177270.d.ts +78 -0
  36. package/dist/contracts-strategies-378a16b7.d.cts +168 -0
  37. package/dist/contracts-strategies-378a16b7.d.ts +168 -0
  38. package/dist/contracts.cjs +181 -0
  39. package/dist/contracts.d.cts +11 -0
  40. package/dist/contracts.d.ts +11 -0
  41. package/dist/contracts.js +4 -0
  42. package/dist/core-141335ac.d.ts +651 -0
  43. package/dist/core-bea2ceca.d.cts +651 -0
  44. package/dist/create-worker-provider-AA5SRII6.js +58 -0
  45. package/dist/create-worker-provider-KJNUSSTW.cjs +60 -0
  46. package/dist/eligibility-ONLNJ6FB.cjs +10 -0
  47. package/dist/eligibility-ULFC3E4G.js +8 -0
  48. package/dist/error-code-map-9c44a425.d.ts +62 -0
  49. package/dist/error-code-map-dd5becfa.d.cts +62 -0
  50. package/dist/i18n/index.cjs +90 -0
  51. package/dist/i18n/index.d.cts +3 -0
  52. package/dist/i18n/index.d.ts +3 -0
  53. package/dist/i18n/index.js +1 -0
  54. package/dist/index.cjs +1770 -0
  55. package/dist/index.d.cts +280 -0
  56. package/dist/index.d.ts +280 -0
  57. package/dist/index.js +1589 -0
  58. package/dist/internal.cjs +2407 -0
  59. package/dist/internal.d.cts +595 -0
  60. package/dist/internal.d.ts +595 -0
  61. package/dist/internal.js +2275 -0
  62. package/dist/pipeline/index.cjs +10 -0
  63. package/dist/pipeline/index.d.cts +11 -0
  64. package/dist/pipeline/index.d.ts +11 -0
  65. package/dist/pipeline/index.js +1 -0
  66. package/dist/pipeline-worker.cjs +199 -0
  67. package/dist/pipeline-worker.d.cts +2 -0
  68. package/dist/pipeline-worker.d.ts +2 -0
  69. package/dist/pipeline-worker.js +197 -0
  70. package/dist/resolve-locale-81feef21.d.ts +20 -0
  71. package/dist/resolve-locale-9cb63600.d.cts +20 -0
  72. package/dist/resolve-theme-01758105.d.ts +53 -0
  73. package/dist/resolve-theme-66cf8d98.d.cts +53 -0
  74. package/dist/server-mode-drive-controller-b5f8ee12.d.cts +180 -0
  75. package/dist/server-mode-drive-controller-b5f8ee12.d.ts +180 -0
  76. package/dist/steps/compress.cjs +66 -0
  77. package/dist/steps/compress.d.cts +10 -0
  78. package/dist/steps/compress.d.ts +10 -0
  79. package/dist/steps/compress.js +64 -0
  80. package/dist/steps/exif.cjs +44 -0
  81. package/dist/steps/exif.d.cts +5 -0
  82. package/dist/steps/exif.d.ts +5 -0
  83. package/dist/steps/exif.js +42 -0
  84. package/dist/steps/hash.cjs +44 -0
  85. package/dist/steps/hash.d.cts +5 -0
  86. package/dist/steps/hash.d.ts +5 -0
  87. package/dist/steps/hash.js +42 -0
  88. package/dist/steps/heic.cjs +59 -0
  89. package/dist/steps/heic.d.cts +5 -0
  90. package/dist/steps/heic.d.ts +5 -0
  91. package/dist/steps/heic.js +57 -0
  92. package/dist/steps/thumbnail.cjs +54 -0
  93. package/dist/steps/thumbnail.d.cts +10 -0
  94. package/dist/steps/thumbnail.d.ts +10 -0
  95. package/dist/steps/thumbnail.js +52 -0
  96. package/dist/strategies/index.cjs +82 -0
  97. package/dist/strategies/index.d.cts +187 -0
  98. package/dist/strategies/index.d.ts +187 -0
  99. package/dist/strategies/index.js +60 -0
  100. package/dist/strategies/tus-upload.cjs +14 -0
  101. package/dist/strategies/tus-upload.d.cts +15 -0
  102. package/dist/strategies/tus-upload.d.ts +15 -0
  103. package/dist/strategies/tus-upload.js +5 -0
  104. package/dist/theme/index.cjs +38 -0
  105. package/dist/theme/index.d.cts +3 -0
  106. package/dist/theme/index.d.ts +3 -0
  107. package/dist/theme/index.js +1 -0
  108. package/dist/theme-store-2e56a674.d.cts +39 -0
  109. package/dist/theme-store-f13e0315.d.ts +39 -0
  110. package/dist/token-endpoint-5fdb4a35.d.ts +20 -0
  111. package/dist/token-endpoint-a7d15ab6.d.cts +20 -0
  112. package/dist/ui-translations-c5d00392.d.cts +455 -0
  113. package/dist/ui-translations-c5d00392.d.ts +455 -0
  114. package/dist/uploader-props-72242002.d.ts +340 -0
  115. package/dist/uploader-props-7f956e60.d.cts +340 -0
  116. package/dist/vars-d3421f6c.d.cts +240 -0
  117. package/dist/vars-d3421f6c.d.ts +240 -0
  118. package/package.json +182 -0
@@ -0,0 +1,365 @@
1
+ // src/theme/presets.ts
2
+ var lightPreset = {
3
+ color: {
4
+ surface: "#FFFFFF",
5
+ surfaceAlt: "#F7F7F8",
6
+ primary: "#0284c7",
7
+ primaryHover: "#0369a1",
8
+ text: "#0B0B0B",
9
+ textMuted: "#6D6D6D",
10
+ border: "#D1D5DB",
11
+ borderActive: "#0ea5e9",
12
+ danger: "#DC2626",
13
+ success: "#16A34A",
14
+ dragBg: "#e0f2fe",
15
+ overlay: "rgba(0, 0, 0, 0.5)"
16
+ },
17
+ radius: {
18
+ sm: "4px",
19
+ md: "8px",
20
+ lg: "12px",
21
+ full: "9999px"
22
+ },
23
+ shadow: {
24
+ sm: "0 1px 2px rgba(0, 0, 0, 0.05)",
25
+ md: "0 4px 6px rgba(0, 0, 0, 0.07)",
26
+ lg: "0 10px 15px rgba(0, 0, 0, 0.1)"
27
+ },
28
+ spacing: {
29
+ xs: "4px",
30
+ sm: "8px",
31
+ md: "12px",
32
+ lg: "16px"
33
+ }
34
+ };
35
+ var darkPreset = {
36
+ color: {
37
+ surface: "#1A1A2E",
38
+ surfaceAlt: "#252540",
39
+ primary: "#38bdf8",
40
+ primaryHover: "#7dd3fc",
41
+ text: "#FFFFFF",
42
+ textMuted: "#D1D5DB",
43
+ border: "#4B5563",
44
+ borderActive: "#38bdf8",
45
+ danger: "#EF4444",
46
+ success: "#22C55E",
47
+ dragBg: "#0b2a3a",
48
+ overlay: "rgba(0, 0, 0, 0.7)"
49
+ },
50
+ radius: {
51
+ sm: "4px",
52
+ md: "8px",
53
+ lg: "12px",
54
+ full: "9999px"
55
+ },
56
+ shadow: {
57
+ sm: "0 1px 2px rgba(0, 0, 0, 0.2)",
58
+ md: "0 4px 6px rgba(0, 0, 0, 0.3)",
59
+ lg: "0 10px 15px rgba(0, 0, 0, 0.4)"
60
+ },
61
+ spacing: {
62
+ xs: "4px",
63
+ sm: "8px",
64
+ md: "12px",
65
+ lg: "16px"
66
+ }
67
+ };
68
+
69
+ // src/theme/resolve-theme.ts
70
+ function deepMerge(base, overrides) {
71
+ if (!overrides) return base;
72
+ const result = { ...base };
73
+ const over = overrides;
74
+ for (const key of Object.keys(over)) {
75
+ const val = over[key];
76
+ if (val !== void 0 && typeof val === "object" && val !== null && !Array.isArray(val) && typeof result[key] === "object" && result[key] !== null) {
77
+ result[key] = deepMerge(
78
+ result[key],
79
+ val
80
+ );
81
+ } else if (val !== void 0) {
82
+ result[key] = val;
83
+ }
84
+ }
85
+ return result;
86
+ }
87
+ function detectSystemMode() {
88
+ if (typeof window !== "undefined" && // matchMedia is absent in jsdom/SSR — keep the optional call. (The
89
+ // no-unnecessary-condition disable that used to sit here became
90
+ // unused when the rule was demoted to off in F-784's warning purge.)
91
+ window.matchMedia?.("(prefers-color-scheme: dark)").matches) {
92
+ return "dark";
93
+ }
94
+ return "light";
95
+ }
96
+ function resolveTheme(config, providerTokens, providerSlots) {
97
+ const mode = config?.mode ?? "light";
98
+ const effectiveMode = mode === "system" ? detectSystemMode() : mode;
99
+ const base = effectiveMode === "dark" ? darkPreset : lightPreset;
100
+ const withProvider = deepMerge(base, providerTokens);
101
+ const final = deepMerge(withProvider, config?.tokens);
102
+ const mergedSlots = deepMerge(
103
+ providerSlots ?? {},
104
+ config?.slots
105
+ );
106
+ return { mode, tokens: final, slots: mergedSlots };
107
+ }
108
+
109
+ // src/theme/vars.ts
110
+ var UPUP_VAR_PREFIX = "--upup-";
111
+ function toKebab(str) {
112
+ return str.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase());
113
+ }
114
+ function tokensToVars(tokens) {
115
+ const vars = {};
116
+ for (const [group, groupTokens] of Object.entries(tokens)) {
117
+ for (const [key, value] of Object.entries(
118
+ groupTokens
119
+ )) {
120
+ const varName = `${UPUP_VAR_PREFIX}${group}-${toKebab(key)}`;
121
+ vars[varName] = value;
122
+ }
123
+ }
124
+ return vars;
125
+ }
126
+ function tokensToVarRefs() {
127
+ const groups = {
128
+ color: [
129
+ "surface",
130
+ "surfaceAlt",
131
+ "primary",
132
+ "primaryHover",
133
+ "text",
134
+ "textMuted",
135
+ "border",
136
+ "borderActive",
137
+ "danger",
138
+ "success",
139
+ "dragBg",
140
+ "overlay"
141
+ ],
142
+ radius: ["sm", "md", "lg", "full"],
143
+ shadow: ["sm", "md", "lg"],
144
+ spacing: ["xs", "sm", "md", "lg"]
145
+ };
146
+ const result = {};
147
+ for (const [group, keys] of Object.entries(groups)) {
148
+ result[group] = {};
149
+ for (const key of keys) {
150
+ result[group][key] = `var(${UPUP_VAR_PREFIX}${group}-${toKebab(key)})`;
151
+ }
152
+ }
153
+ return result;
154
+ }
155
+
156
+ // src/theme/slots.ts
157
+ var SLOT_TO_FLAT = {
158
+ uploader: {
159
+ root: "containerFull",
160
+ container: "containerFull"
161
+ },
162
+ dropZone: {
163
+ root: "containerFull"
164
+ },
165
+ sourceSelector: {
166
+ root: "containerFull",
167
+ sourceList: "sourceButtonList",
168
+ sourceButton: "sourceButton",
169
+ sourceButtonIcon: "sourceButtonIcon",
170
+ sourceButtonText: "sourceButtonText",
171
+ browseText: "sourceButtonText",
172
+ dragText: "sourceButtonText"
173
+ },
174
+ sourceView: {
175
+ root: "sourceView",
176
+ header: "sourceViewHeader",
177
+ cancelButton: "sourceViewCancelButton"
178
+ },
179
+ fileList: {
180
+ root: "fileListContainer",
181
+ header: "containerHeader",
182
+ cancelButton: "containerCancelButton",
183
+ addMoreButton: "containerAddMoreButton",
184
+ fileCount: "containerHeader",
185
+ body: [
186
+ "fileListContainerInnerSingle",
187
+ "fileListContainerInnerMultiple"
188
+ ],
189
+ footer: "fileListFooter",
190
+ uploadButton: "uploadButton",
191
+ doneButton: "uploadDoneButton"
192
+ },
193
+ filePreview: {
194
+ root: ["fileItemSingle", "fileItemMultiple"],
195
+ thumbnail: ["fileThumbnailSingle", "fileThumbnailMultiple"],
196
+ icon: "fileIcon",
197
+ info: "fileInfo",
198
+ name: "fileName",
199
+ size: "fileSize",
200
+ previewButton: "filePreviewButton",
201
+ deleteButton: "fileDeleteButton"
202
+ },
203
+ progressBar: {
204
+ root: "progressBarContainer",
205
+ track: "progressBar",
206
+ fill: "progressBarInner",
207
+ text: "progressBarText"
208
+ },
209
+ notifier: {
210
+ root: "containerFull",
211
+ message: "containerFull"
212
+ },
213
+ urlUploader: {
214
+ input: "urlInput",
215
+ fetchButton: "urlFetchButton"
216
+ },
217
+ cameraUploader: {
218
+ previewContainer: "cameraPreviewContainer",
219
+ deleteButton: "cameraDeleteButton",
220
+ captureButton: "cameraCaptureButton",
221
+ rotateButton: "cameraRotateButton",
222
+ mirrorButton: "cameraRotateButton",
223
+ addButton: "cameraAddButton",
224
+ modeToggle: "cameraRotateButton",
225
+ videoRecordButton: "cameraCaptureButton",
226
+ videoStopButton: "cameraCaptureButton",
227
+ videoPreview: "cameraPreviewContainer",
228
+ videoAddButton: "cameraAddButton",
229
+ videoDeleteButton: "cameraDeleteButton"
230
+ },
231
+ audioUploader: {
232
+ root: "containerFull",
233
+ playbackContainer: "cameraPreviewContainer",
234
+ deleteButton: "cameraDeleteButton",
235
+ addButton: "cameraAddButton"
236
+ },
237
+ screenCaptureUploader: {
238
+ root: "containerFull",
239
+ preview: "cameraPreviewContainer",
240
+ addButton: "cameraAddButton",
241
+ deleteButton: "cameraDeleteButton"
242
+ },
243
+ driveBrowser: {
244
+ root: "containerFull",
245
+ header: "driveHeader",
246
+ searchContainer: "driveSearchContainer",
247
+ searchInput: "driveSearchInput",
248
+ body: "driveBody",
249
+ footer: "driveFooter",
250
+ itemDefault: "driveItemContainerDefault",
251
+ itemSelected: "driveItemContainerSelected",
252
+ itemInner: "driveItemContainerInner",
253
+ itemInnerText: "driveItemInnerText",
254
+ addFilesButton: "driveAddFilesButton",
255
+ cancelFilesButton: "driveCancelFilesButton",
256
+ logoutButton: "driveLogoutButton",
257
+ loading: "driveLoading"
258
+ },
259
+ driveAuthFallback: {
260
+ root: "containerFull"
261
+ },
262
+ filePreviewPortal: {
263
+ root: "filePreviewPortal"
264
+ },
265
+ imageEditor: {
266
+ root: "containerFull",
267
+ modal: "containerFull"
268
+ }
269
+ };
270
+ function flattenSlotsToClassNames(slots) {
271
+ if (!slots) return {};
272
+ const out = {};
273
+ for (const componentKey of Object.keys(slots)) {
274
+ const component = slots[componentKey];
275
+ if (!component) continue;
276
+ const mapping = SLOT_TO_FLAT[componentKey];
277
+ if (!mapping) continue;
278
+ for (const slotName of Object.keys(component)) {
279
+ const value = component[slotName];
280
+ if (typeof value !== "string" || value.length === 0) continue;
281
+ const target = mapping[slotName];
282
+ if (!target) continue;
283
+ const keys = Array.isArray(target) ? target : [target];
284
+ for (const key of keys) {
285
+ out[key] = out[key] ? `${out[key]} ${value}` : value;
286
+ }
287
+ }
288
+ }
289
+ return out;
290
+ }
291
+
292
+ // src/theme/theme-store.ts
293
+ function themeConfigEqual(a, b) {
294
+ if (a === b) return true;
295
+ return a?.mode === b?.mode && JSON.stringify(a?.tokens) === JSON.stringify(b?.tokens) && JSON.stringify(a?.slots) === JSON.stringify(b?.slots);
296
+ }
297
+ var ThemeStore = class {
298
+ constructor(config) {
299
+ this.listeners = /* @__PURE__ */ new Set();
300
+ this.systemMode = "light";
301
+ this.mediaCleanup = null;
302
+ this.subscribe = (listener) => {
303
+ this.listeners.add(listener);
304
+ return () => this.listeners.delete(listener);
305
+ };
306
+ this.getSnapshot = () => this.state;
307
+ this.config = config;
308
+ this.state = this.compute();
309
+ }
310
+ /** Start the `system` matchMedia subscription (no-op for explicit modes / SSR). */
311
+ init() {
312
+ const requested = this.config?.mode ?? "light";
313
+ if (requested !== "system") return;
314
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function")
315
+ return;
316
+ const media = window.matchMedia("(prefers-color-scheme: dark)");
317
+ const update = () => {
318
+ this.systemMode = media.matches ? "dark" : "light";
319
+ this.recompute();
320
+ };
321
+ update();
322
+ media.addEventListener("change", update);
323
+ this.mediaCleanup = () => {
324
+ media.removeEventListener("change", update);
325
+ };
326
+ }
327
+ /** Re-resolve when the host's theme config prop changes. */
328
+ setThemeConfig(config) {
329
+ if (themeConfigEqual(this.config, config)) return;
330
+ this.config = config;
331
+ this.recompute();
332
+ }
333
+ compute() {
334
+ const requested = this.config?.mode ?? "light";
335
+ const effective = requested === "system" ? this.systemMode : requested;
336
+ const resolved = resolveTheme({
337
+ ...this.config ?? {},
338
+ mode: effective
339
+ });
340
+ return {
341
+ themeMode: effective,
342
+ isDark: effective === "dark",
343
+ tokens: resolved.tokens,
344
+ resolved,
345
+ slotOverrides: flattenSlotsToClassNames(resolved.slots),
346
+ slots: resolved.slots
347
+ };
348
+ }
349
+ recompute() {
350
+ this.state = this.compute();
351
+ this.notify();
352
+ }
353
+ notify() {
354
+ this.listeners.forEach((fn) => {
355
+ fn();
356
+ });
357
+ }
358
+ destroy() {
359
+ this.mediaCleanup?.();
360
+ this.mediaCleanup = null;
361
+ this.listeners.clear();
362
+ }
363
+ };
364
+
365
+ export { ThemeStore, UPUP_VAR_PREFIX, darkPreset, flattenSlotsToClassNames, lightPreset, resolveTheme, tokensToVarRefs, tokensToVars };
@@ -0,0 +1,56 @@
1
+ // src/types/file-source.ts
2
+ var FileSource = /* @__PURE__ */ ((FileSource2) => {
3
+ FileSource2["LOCAL"] = "local";
4
+ FileSource2["GOOGLE_DRIVE"] = "googleDrive";
5
+ FileSource2["ONE_DRIVE"] = "oneDrive";
6
+ FileSource2["DROPBOX"] = "dropbox";
7
+ FileSource2["BOX"] = "box";
8
+ FileSource2["URL"] = "url";
9
+ FileSource2["CAMERA"] = "camera";
10
+ FileSource2["MICROPHONE"] = "microphone";
11
+ FileSource2["SCREEN"] = "screen";
12
+ return FileSource2;
13
+ })(FileSource || {});
14
+
15
+ // src/types/storage-provider.ts
16
+ var StorageProvider = /* @__PURE__ */ ((StorageProvider2) => {
17
+ StorageProvider2["AWS"] = "aws";
18
+ StorageProvider2["Azure"] = "azure";
19
+ StorageProvider2["BackBlaze"] = "backblaze";
20
+ StorageProvider2["DigitalOcean"] = "digitalocean";
21
+ StorageProvider2["CloudflareR2"] = "r2";
22
+ StorageProvider2["Wasabi"] = "wasabi";
23
+ StorageProvider2["MinIO"] = "minio";
24
+ StorageProvider2["GCS"] = "gcs";
25
+ StorageProvider2["Supabase"] = "supabase";
26
+ StorageProvider2["Hetzner"] = "hetzner";
27
+ StorageProvider2["Linode"] = "linode";
28
+ StorageProvider2["Vultr"] = "vultr";
29
+ StorageProvider2["UpCloud"] = "upcloud";
30
+ StorageProvider2["Scaleway"] = "scaleway";
31
+ StorageProvider2["OVHcloud"] = "ovhcloud";
32
+ StorageProvider2["Alibaba"] = "alibaba";
33
+ StorageProvider2["Oracle"] = "oracle";
34
+ StorageProvider2["Contabo"] = "contabo";
35
+ StorageProvider2["Storj"] = "storj";
36
+ StorageProvider2["IDrive"] = "idrive";
37
+ StorageProvider2["Ceph"] = "ceph";
38
+ return StorageProvider2;
39
+ })(StorageProvider || {});
40
+ var NON_S3_STORAGE_PROVIDERS = /* @__PURE__ */ new Set([
41
+ "azure" /* Azure */
42
+ ]);
43
+
44
+ // src/types/upload-status.ts
45
+ var UploadStatus = /* @__PURE__ */ ((UploadStatus2) => {
46
+ UploadStatus2["IDLE"] = "IDLE";
47
+ UploadStatus2["PROCESSING"] = "PROCESSING";
48
+ UploadStatus2["READY"] = "READY";
49
+ UploadStatus2["UPLOADING"] = "UPLOADING";
50
+ UploadStatus2["PAUSED"] = "PAUSED";
51
+ UploadStatus2["SUCCESSFUL"] = "SUCCESSFUL";
52
+ UploadStatus2["FAILED"] = "FAILED";
53
+ return UploadStatus2;
54
+ })(UploadStatus || {});
55
+
56
+ export { FileSource, NON_S3_STORAGE_PROVIDERS, StorageProvider, UploadStatus };
@@ -0,0 +1,207 @@
1
+ import { a as UploadFile, c as UploadStatus, F as FileSource } from './contracts-pipeline-cf177270.cjs';
2
+ import { F as FilesProgressMap, R as ResolvedImageEditorOptions, U as UpupCore, b as CloudDrivesConfig } from './core-bea2ceca.cjs';
3
+ import { c as Translations, T as Translator } from './ui-translations-c5d00392.cjs';
4
+ import { e as UpupThemeMode, d as UpupThemeTokens, I as InternalFlatClassNames, l as DeepPartialSlots, g as UpupResolvedTheme } from './vars-d3421f6c.cjs';
5
+
6
+ interface UploadProgressInfo {
7
+ loaded: number;
8
+ total: number;
9
+ percentage: number;
10
+ }
11
+ interface OrchestratorState {
12
+ files: Map<string, UploadFile>;
13
+ uploadStatus: UploadStatus;
14
+ uploadError: string;
15
+ /** Machine code from a typed UpupError (e.g. 'SignatureDoesNotMatch', 'bad_signature'), when the failure carried one. */
16
+ uploadErrorCode?: string | undefined;
17
+ totalProgress: number;
18
+ filesProgressMap: FilesProgressMap;
19
+ uploadSpeed: number;
20
+ uploadEta: number;
21
+ uploadedBytes: number;
22
+ totalBytes: number;
23
+ activeSource?: FileSource | undefined;
24
+ editingFile: UploadFile | null;
25
+ editorQueue: UploadFile[];
26
+ isAddingMore: boolean;
27
+ viewMode: 'grid' | 'list';
28
+ isOnline: boolean;
29
+ }
30
+ interface OrchestratorCallbacks {
31
+ onError?: ((message: string) => void) | undefined;
32
+ onWarn?: ((message: string) => void) | undefined;
33
+ onUploadComplete?: ((files: UploadFile[]) => void) | undefined;
34
+ onUploadStart?: (() => void) | undefined;
35
+ onFileUploadStart?: ((file: UploadFile) => void) | undefined;
36
+ onFileUploadProgress?: ((file: UploadFile, progress: UploadProgressInfo) => void) | undefined;
37
+ onFileUploadComplete?: ((file: UploadFile, key: string) => void) | undefined;
38
+ onFilesUploadProgress?: ((completedFiles: number, totalFiles: number) => void) | undefined;
39
+ onFilesUploadComplete?: ((files: UploadFile[]) => void) | undefined;
40
+ onFileRemoved?: ((file: UploadFile) => void) | undefined;
41
+ onFilesSelected?: ((files: UploadFile[]) => void) | undefined;
42
+ onFileDrop?: ((files: File[]) => void) | undefined;
43
+ onDoneClicked?: (() => void) | undefined;
44
+ onPrepareFiles?: ((files: UploadFile[]) => Promise<UploadFile[] | File[]> | UploadFile[] | File[]) | undefined;
45
+ imageEditorOptions?: ResolvedImageEditorOptions | undefined;
46
+ /** When true, triggers upload automatically after files are added. */
47
+ autoUpload?: boolean | undefined;
48
+ }
49
+
50
+ declare class UploaderOrchestrator {
51
+ private state;
52
+ private listeners;
53
+ private core;
54
+ private callbacks;
55
+ private unsubs;
56
+ private disposed;
57
+ constructor(core: UpupCore, callbacks: OrchestratorCallbacks);
58
+ /** useSyncExternalStore-compatible subscribe (bound). */
59
+ subscribe: (listener: () => void) => (() => void);
60
+ /** useSyncExternalStore-compatible getSnapshot (bound). */
61
+ getSnapshot: () => OrchestratorState;
62
+ protected setState(partial: Partial<OrchestratorState>): void;
63
+ private notify;
64
+ /** Remove a file by id: revoke its blob URL, then delegate to core. */
65
+ removeFile(fileId: string): void;
66
+ /** Set the active upload source. */
67
+ setActiveSource(source: FileSource | undefined): void;
68
+ /** Toggle between grid and list view. */
69
+ setViewMode(mode: 'grid' | 'list'): void;
70
+ /** Toggle the "adding more files" state. */
71
+ setIsAddingMore(value: boolean): void;
72
+ /** Trigger upload for all current files. Calls onPrepareFiles if provided. */
73
+ startUpload(): Promise<UploadFile[] | undefined>;
74
+ /** Retry upload for a specific file or all failed files. */
75
+ retryUpload(fileId?: string): Promise<UploadFile[] | undefined>;
76
+ /** Cancel in-progress upload, revoke blob URLs, clear all files and progress. */
77
+ handleCancel(): void;
78
+ /** Pause in-progress upload. */
79
+ handlePause(): void;
80
+ /** Resume paused upload. */
81
+ handleResume(): void;
82
+ /** Mark upload as done: invoke callback, emit event, then cancel/clear. */
83
+ handleDone(): void;
84
+ /** Full state reset: clear isAddingMore, emit state-reset, then handleDone. */
85
+ resetState(): void;
86
+ /** Open the image editor for a given file. Invokes onOpen callback and emits event. */
87
+ openImageEditor(file: UploadFile): void;
88
+ /**
89
+ * Close the image editor without saving. Invokes onCancel callback.
90
+ * If the editor queue is non-empty, the next file is automatically opened.
91
+ */
92
+ closeImageEditor(): void;
93
+ /**
94
+ * Save an edited image. Converts the data URL to a blob, creates a new
95
+ * UploadFile preserving the original's identity, replaces it in state
96
+ * and core, then invokes the onSave callback.
97
+ */
98
+ saveImageEdit(editedImageData: string, mimeType?: string): void;
99
+ /** Replace a single file in state by id (revokes old blob URL). Also replaces in core. */
100
+ replaceFile(fileId: string, newFile: UploadFile): void;
101
+ /** Enqueue files for auto-opening in the image editor. */
102
+ enqueueForEditor(files: UploadFile[]): void;
103
+ /** Pop the next file from the editor queue and open it. */
104
+ private processEditorQueue;
105
+ private speedSamples;
106
+ /**
107
+ * Project orchestrator state from core — the single source of truth (F-145).
108
+ * `uploadStatus` is derived from the `status` each status-carrying `state-change`
109
+ * event supplies (core sets `_status` before every such emit); the discrete
110
+ * upload-start/upload-all-complete/upload-error listeners no longer write it. `files`
111
+ * is rebuilt from `core.files`, and is a no-op when the file set is unchanged (same
112
+ * size + ordered ids + same UploadFile refs) so the `files` reference stays stable
113
+ * across the many status-only `state-change` events core emits during upload —
114
+ * preserving referential stability for useSyncExternalStore / computed consumers.
115
+ */
116
+ private projectFromCore;
117
+ private filesProjectionChanged;
118
+ init(): void;
119
+ destroy(): void;
120
+ }
121
+
122
+ /**
123
+ * Base context shape types shared across the framework bindings.
124
+ *
125
+ * Each framework package defines its own concrete context types that extend
126
+ * these bases with framework-specific fields (e.g. React refs, Vue refs,
127
+ * Dispatch<SetStateAction<...>> vs plain setters).
128
+ *
129
+ * This file intentionally uses plain function signatures for state setters
130
+ * so both React (Dispatch<SetStateAction<T>>) and Vue ((v: T) => void) are
131
+ * compatible supertypes.
132
+ */
133
+
134
+ type BaseContextUpload = {
135
+ uploadStatus: UploadStatus;
136
+ uploadError?: string | undefined;
137
+ /** Machine code from a typed UpupError, when the failure carried one. */
138
+ uploadErrorCode?: string | undefined;
139
+ totalProgress: number;
140
+ filesProgressMap: FilesProgressMap;
141
+ startUpload: () => Promise<UploadFile[] | undefined>;
142
+ retryUpload: (fileId?: string) => Promise<UploadFile[] | undefined>;
143
+ uploadSpeed: number;
144
+ uploadEta: number;
145
+ uploadedBytes: number;
146
+ totalBytes: number;
147
+ };
148
+ type BaseContextRuntime = {
149
+ core: UpupCore | null;
150
+ orchestrator: UploaderOrchestrator | null;
151
+ mode: 'client' | 'server';
152
+ serverUrl?: string | undefined;
153
+ openFilePicker: () => void;
154
+ isOnline: boolean;
155
+ };
156
+ type BaseContextSource = {
157
+ activeSource?: FileSource | undefined;
158
+ setActiveSource: (source: FileSource | undefined) => void;
159
+ cloudDrives?: CloudDrivesConfig | undefined;
160
+ };
161
+ type BaseContextI18n = {
162
+ translations: Translations;
163
+ translator?: Translator | undefined;
164
+ lang: string;
165
+ dir: 'ltr' | 'rtl';
166
+ };
167
+ type BaseContextFiles = {
168
+ files: Map<string, UploadFile>;
169
+ setFiles: (newFiles: File[]) => void;
170
+ replaceFiles: (files: File[] | UploadFile[]) => void;
171
+ resetState: () => void;
172
+ uploadFiles: (files: File[] | UploadFile[]) => Promise<UploadFile[] | undefined>;
173
+ handleFileRemove: (fileId: string) => void;
174
+ };
175
+ type BaseContextUploadControls = {
176
+ upload: BaseContextUpload;
177
+ handleDone: () => void;
178
+ handleCancel: () => void;
179
+ handlePause: () => void;
180
+ handleResume: () => void;
181
+ };
182
+ type BaseContextView = {
183
+ isAddingMore: boolean;
184
+ setIsAddingMore: (value: boolean) => void;
185
+ viewMode: 'grid' | 'list';
186
+ setViewMode: (mode: 'grid' | 'list') => void;
187
+ };
188
+ type BaseContextEditor = {
189
+ editingFile: UploadFile | null;
190
+ openImageEditor: (file: UploadFile) => void;
191
+ closeImageEditor: () => void;
192
+ saveImageEdit: (editedImageData: string, mimeType?: string) => void;
193
+ replaceFile: (fileId: string, newFile: UploadFile) => void;
194
+ };
195
+ type BaseResolvedTheme = Omit<UpupResolvedTheme, 'mode'> & {
196
+ mode: Exclude<UpupThemeMode, 'system'>;
197
+ };
198
+ type BaseContextTheme = {
199
+ themeMode: Exclude<UpupThemeMode, 'system'>;
200
+ isDark: boolean;
201
+ tokens: UpupThemeTokens;
202
+ resolved: BaseResolvedTheme;
203
+ slotOverrides: InternalFlatClassNames;
204
+ slots: DeepPartialSlots;
205
+ };
206
+
207
+ export { type BaseContextUpload as B, type OrchestratorCallbacks as O, UploaderOrchestrator as U, type BaseContextRuntime as a, type BaseContextSource as b, type BaseContextI18n as c, type BaseContextFiles as d, type BaseContextUploadControls as e, type BaseContextView as f, type BaseContextEditor as g, type BaseContextTheme as h, type OrchestratorState as i, type UploadProgressInfo as j };