@ai-matrx/media 0.4.5 → 0.5.1

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/react.d.cts CHANGED
@@ -280,16 +280,6 @@ interface FileUploadDropzoneProps {
280
280
  }
281
281
  declare function FileUploadDropzone({ uploadOptions, accept, maxSize, enablePaste, mode, children, className, actions, onUploadStart, onUploaded, onError, onOpenFile, pickerEventName, }: FileUploadDropzoneProps): react.JSX.Element;
282
282
 
283
- /**
284
- * Human file size.
285
- *
286
- * `null` / `undefined` / NaN / negative collapse to an em-dash, NOT to
287
- * "0 B" (fixed at 0.4.0 while absorbing the viewer bodies — matrx-frontend's
288
- * `formatFileSize` already had this guard and the package's did not, so a
289
- * corrupt or mid-upload `size` row rendered as a confident, wrong "0 B"
290
- * instead of an honest "size unknown").
291
- */
292
- declare function formatFileSize(bytes: number | null | undefined): string;
293
283
  interface UploadProgressListProps {
294
284
  uploads: MediaUploadEntry[];
295
285
  /** Remove an entry from the tray (wire to `useMediaUpload().clearEntry`). */
@@ -350,4 +340,4 @@ interface MediaLightboxProps {
350
340
  }
351
341
  declare function MediaLightbox({ open, onClose, mediaRef, fileName, alt, as, autoPlay, playsInline, poster, playbackLabel, actions, hideUnavailableActions, headerExtra, className, }: MediaLightboxProps): react.JSX.Element | null;
352
342
 
353
- export { AlertCircleIcon, ArchiveIcon, BracesIcon, CheckCircle2Icon, CheckIcon, CodeIcon, CopyIcon, DatabaseIcon, DownloadIcon, ExternalLinkIcon, FileAudioIcon, FileCodeIcon, FileIcon, type FileIconProps, FileJsonIcon, FileSpreadsheetIcon, FileTextIcon, FileTypeIcon, FileUploadDropzone, type FileUploadDropzoneActions, type FileUploadDropzoneProps, FileVideoIcon, FolderIcon, FolderOpenIcon, GlobeIcon, ImageIcon, ImageOffIcon, InlineMediaRef, type InlineMediaRefFit, type InlineMediaRefProps, type InlineMediaRefSize, Link2Icon, MediaActionToolbar, type MediaActionToolbarProps, type MediaDropzoneOptions, type MediaDropzoneState, type MediaIconProps, MediaLightbox, type MediaLightboxProps, MediaThumbnail, type MediaThumbnailProps, MusicIcon, PackageBoxIcon, PenToolIcon, PlusIcon, SearchIcon, Settings2Icon, Share2Icon, SpinnerIcon, SubtitlesIcon, UploadIcon, UploadProgressList, type UploadProgressListProps, VideoIcon, VideoOffIcon, VolumeXIcon, XIcon, cn, formatFileSize, useMediaDropzone };
343
+ export { AlertCircleIcon, ArchiveIcon, BracesIcon, CheckCircle2Icon, CheckIcon, CodeIcon, CopyIcon, DatabaseIcon, DownloadIcon, ExternalLinkIcon, FileAudioIcon, FileCodeIcon, FileIcon, type FileIconProps, FileJsonIcon, FileSpreadsheetIcon, FileTextIcon, FileTypeIcon, FileUploadDropzone, type FileUploadDropzoneActions, type FileUploadDropzoneProps, FileVideoIcon, FolderIcon, FolderOpenIcon, GlobeIcon, ImageIcon, ImageOffIcon, InlineMediaRef, type InlineMediaRefFit, type InlineMediaRefProps, type InlineMediaRefSize, Link2Icon, MediaActionToolbar, type MediaActionToolbarProps, type MediaDropzoneOptions, type MediaDropzoneState, type MediaIconProps, MediaLightbox, type MediaLightboxProps, MediaThumbnail, type MediaThumbnailProps, MusicIcon, PackageBoxIcon, PenToolIcon, PlusIcon, SearchIcon, Settings2Icon, Share2Icon, SpinnerIcon, SubtitlesIcon, UploadIcon, UploadProgressList, type UploadProgressListProps, VideoIcon, VideoOffIcon, VolumeXIcon, XIcon, cn, useMediaDropzone };
package/dist/react.d.ts CHANGED
@@ -280,16 +280,6 @@ interface FileUploadDropzoneProps {
280
280
  }
281
281
  declare function FileUploadDropzone({ uploadOptions, accept, maxSize, enablePaste, mode, children, className, actions, onUploadStart, onUploaded, onError, onOpenFile, pickerEventName, }: FileUploadDropzoneProps): react.JSX.Element;
282
282
 
283
- /**
284
- * Human file size.
285
- *
286
- * `null` / `undefined` / NaN / negative collapse to an em-dash, NOT to
287
- * "0 B" (fixed at 0.4.0 while absorbing the viewer bodies — matrx-frontend's
288
- * `formatFileSize` already had this guard and the package's did not, so a
289
- * corrupt or mid-upload `size` row rendered as a confident, wrong "0 B"
290
- * instead of an honest "size unknown").
291
- */
292
- declare function formatFileSize(bytes: number | null | undefined): string;
293
283
  interface UploadProgressListProps {
294
284
  uploads: MediaUploadEntry[];
295
285
  /** Remove an entry from the tray (wire to `useMediaUpload().clearEntry`). */
@@ -350,4 +340,4 @@ interface MediaLightboxProps {
350
340
  }
351
341
  declare function MediaLightbox({ open, onClose, mediaRef, fileName, alt, as, autoPlay, playsInline, poster, playbackLabel, actions, hideUnavailableActions, headerExtra, className, }: MediaLightboxProps): react.JSX.Element | null;
352
342
 
353
- export { AlertCircleIcon, ArchiveIcon, BracesIcon, CheckCircle2Icon, CheckIcon, CodeIcon, CopyIcon, DatabaseIcon, DownloadIcon, ExternalLinkIcon, FileAudioIcon, FileCodeIcon, FileIcon, type FileIconProps, FileJsonIcon, FileSpreadsheetIcon, FileTextIcon, FileTypeIcon, FileUploadDropzone, type FileUploadDropzoneActions, type FileUploadDropzoneProps, FileVideoIcon, FolderIcon, FolderOpenIcon, GlobeIcon, ImageIcon, ImageOffIcon, InlineMediaRef, type InlineMediaRefFit, type InlineMediaRefProps, type InlineMediaRefSize, Link2Icon, MediaActionToolbar, type MediaActionToolbarProps, type MediaDropzoneOptions, type MediaDropzoneState, type MediaIconProps, MediaLightbox, type MediaLightboxProps, MediaThumbnail, type MediaThumbnailProps, MusicIcon, PackageBoxIcon, PenToolIcon, PlusIcon, SearchIcon, Settings2Icon, Share2Icon, SpinnerIcon, SubtitlesIcon, UploadIcon, UploadProgressList, type UploadProgressListProps, VideoIcon, VideoOffIcon, VolumeXIcon, XIcon, cn, formatFileSize, useMediaDropzone };
343
+ export { AlertCircleIcon, ArchiveIcon, BracesIcon, CheckCircle2Icon, CheckIcon, CodeIcon, CopyIcon, DatabaseIcon, DownloadIcon, ExternalLinkIcon, FileAudioIcon, FileCodeIcon, FileIcon, type FileIconProps, FileJsonIcon, FileSpreadsheetIcon, FileTextIcon, FileTypeIcon, FileUploadDropzone, type FileUploadDropzoneActions, type FileUploadDropzoneProps, FileVideoIcon, FolderIcon, FolderOpenIcon, GlobeIcon, ImageIcon, ImageOffIcon, InlineMediaRef, type InlineMediaRefFit, type InlineMediaRefProps, type InlineMediaRefSize, Link2Icon, MediaActionToolbar, type MediaActionToolbarProps, type MediaDropzoneOptions, type MediaDropzoneState, type MediaIconProps, MediaLightbox, type MediaLightboxProps, MediaThumbnail, type MediaThumbnailProps, MusicIcon, PackageBoxIcon, PenToolIcon, PlusIcon, SearchIcon, Settings2Icon, Share2Icon, SpinnerIcon, SubtitlesIcon, UploadIcon, UploadProgressList, type UploadProgressListProps, VideoIcon, VideoOffIcon, VolumeXIcon, XIcon, cn, useMediaDropzone };
package/dist/react.js CHANGED
@@ -1392,7 +1392,9 @@ function useThumbnailSource(ref, options = {}) {
1392
1392
  mode: "thumbnail",
1393
1393
  loading: false,
1394
1394
  resolution,
1395
- recoverable: explicitThumb.recoverable !== false
1395
+ recoverable: explicitThumb.recoverable !== false,
1396
+ blobBacked: false,
1397
+ retryBlob: blob.retry
1396
1398
  };
1397
1399
  }
1398
1400
  if (resolution?.thumbnailSrc) {
@@ -1401,7 +1403,9 @@ function useThumbnailSource(ref, options = {}) {
1401
1403
  mode: "thumbnail",
1402
1404
  loading: false,
1403
1405
  resolution,
1404
- recoverable: resolution.recoverable !== false
1406
+ recoverable: resolution.recoverable !== false,
1407
+ blobBacked: false,
1408
+ retryBlob: blob.retry
1405
1409
  };
1406
1410
  }
1407
1411
  if (allowSourceFallback && resolution) {
@@ -1411,7 +1415,9 @@ function useThumbnailSource(ref, options = {}) {
1411
1415
  mode: blob.url ? resolution.kind === "video" ? "live-video-poster" : "live-image" : "icon",
1412
1416
  loading: blob.loading,
1413
1417
  resolution,
1414
- recoverable: false
1418
+ recoverable: false,
1419
+ blobBacked: true,
1420
+ retryBlob: blob.retry
1415
1421
  };
1416
1422
  }
1417
1423
  if (resolution.kind === "image") {
@@ -1420,7 +1426,9 @@ function useThumbnailSource(ref, options = {}) {
1420
1426
  mode: "live-image",
1421
1427
  loading: false,
1422
1428
  resolution,
1423
- recoverable: resolution.recoverable !== false
1429
+ recoverable: resolution.recoverable !== false,
1430
+ blobBacked: false,
1431
+ retryBlob: blob.retry
1424
1432
  };
1425
1433
  }
1426
1434
  if (resolution.kind === "video") {
@@ -1429,7 +1437,9 @@ function useThumbnailSource(ref, options = {}) {
1429
1437
  mode: "live-video-poster",
1430
1438
  loading: false,
1431
1439
  resolution,
1432
- recoverable: resolution.recoverable !== false
1440
+ recoverable: resolution.recoverable !== false,
1441
+ blobBacked: false,
1442
+ retryBlob: blob.retry
1433
1443
  };
1434
1444
  }
1435
1445
  }
@@ -1438,7 +1448,9 @@ function useThumbnailSource(ref, options = {}) {
1438
1448
  mode: "icon",
1439
1449
  loading: false,
1440
1450
  resolution,
1441
- recoverable: false
1451
+ recoverable: false,
1452
+ blobBacked: false,
1453
+ retryBlob: blob.retry
1442
1454
  };
1443
1455
  }
1444
1456
 
@@ -1468,6 +1480,8 @@ function MediaThumbnail({
1468
1480
  url: source.src,
1469
1481
  mediaRef,
1470
1482
  recoverable: source.recoverable,
1483
+ blobBacked: source.blobBacked,
1484
+ retryBlob: source.retryBlob,
1471
1485
  fallback
1472
1486
  }
1473
1487
  );
@@ -1479,6 +1493,8 @@ function MediaThumbnail({
1479
1493
  alt: fileName,
1480
1494
  mediaRef,
1481
1495
  recoverable: source.recoverable,
1496
+ blobBacked: source.blobBacked,
1497
+ retryBlob: source.retryBlob,
1482
1498
  fallback
1483
1499
  }
1484
1500
  );
@@ -1497,13 +1513,21 @@ function ImageThumb({
1497
1513
  alt,
1498
1514
  mediaRef,
1499
1515
  recoverable,
1516
+ blobBacked,
1517
+ retryBlob,
1500
1518
  fallback
1501
1519
  }) {
1502
1520
  const { retryKey, onLoadError, failed } = useMediaLoadRecovery(url, {
1503
1521
  recoverable,
1504
1522
  failureRef: mediaRef
1505
1523
  });
1506
- if (failed) return /* @__PURE__ */ jsx4(Fragment2, { children: fallback });
1524
+ const blobRecovery = useMediaBlobLoadRecovery(
1525
+ blobBacked ? mediaRef : null,
1526
+ blobBacked ? url : null,
1527
+ { onRetry: retryBlob }
1528
+ );
1529
+ const activeRecovery = blobBacked ? { retryKey: 0, ...blobRecovery } : { retryKey, onLoadError, failed };
1530
+ if (activeRecovery.failed) return /* @__PURE__ */ jsx4(Fragment2, { children: fallback });
1507
1531
  return /* @__PURE__ */ jsx4(
1508
1532
  "img",
1509
1533
  {
@@ -1511,21 +1535,29 @@ function ImageThumb({
1511
1535
  alt,
1512
1536
  loading: url.startsWith("blob:") ? "eager" : "lazy",
1513
1537
  className: "h-full w-full object-cover",
1514
- onError: onLoadError
1538
+ onError: activeRecovery.onLoadError
1515
1539
  },
1516
- retryKey
1540
+ activeRecovery.retryKey
1517
1541
  );
1518
1542
  }
1519
1543
  function VideoPosterThumb({
1520
1544
  url,
1521
1545
  mediaRef,
1522
1546
  recoverable,
1547
+ blobBacked,
1548
+ retryBlob,
1523
1549
  fallback
1524
1550
  }) {
1525
1551
  const { retryKey, onLoadError, failed } = useMediaLoadRecovery(url, {
1526
1552
  recoverable,
1527
1553
  failureRef: mediaRef
1528
1554
  });
1555
+ const blobRecovery = useMediaBlobLoadRecovery(
1556
+ blobBacked ? mediaRef : null,
1557
+ blobBacked ? url : null,
1558
+ { onRetry: retryBlob }
1559
+ );
1560
+ const activeRecovery = blobBacked ? { retryKey: 0, ...blobRecovery } : { retryKey, onLoadError, failed };
1529
1561
  const ref = useRef5(null);
1530
1562
  useEffect6(() => {
1531
1563
  const v = ref.current;
@@ -1539,7 +1571,7 @@ function VideoPosterThumb({
1539
1571
  v.addEventListener("loadedmetadata", onMeta);
1540
1572
  return () => v.removeEventListener("loadedmetadata", onMeta);
1541
1573
  }, []);
1542
- if (failed) return /* @__PURE__ */ jsx4(Fragment2, { children: fallback });
1574
+ if (activeRecovery.failed) return /* @__PURE__ */ jsx4(Fragment2, { children: fallback });
1543
1575
  return /* @__PURE__ */ jsx4(
1544
1576
  "video",
1545
1577
  {
@@ -1549,9 +1581,9 @@ function VideoPosterThumb({
1549
1581
  preload: "metadata",
1550
1582
  muted: true,
1551
1583
  playsInline: true,
1552
- onError: onLoadError
1584
+ onError: activeRecovery.onLoadError
1553
1585
  },
1554
- retryKey
1586
+ activeRecovery.retryKey
1555
1587
  );
1556
1588
  }
1557
1589
 
@@ -1838,20 +1870,9 @@ function useMediaUpload() {
1838
1870
 
1839
1871
  // src/react/upload-progress-list.tsx
1840
1872
  import { memo, useEffect as useEffect8, useRef as useRef8, useState as useState7 } from "react";
1873
+ import { formatFileSize } from "@ai-matrx/kit/format";
1841
1874
  import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
1842
1875
  var AUTO_DISMISS_MS = 1e4;
1843
- function formatFileSize(bytes) {
1844
- if (bytes == null || !Number.isFinite(bytes) || bytes < 0) return "\u2014";
1845
- if (bytes < 1024) return `${bytes} B`;
1846
- const units = ["KB", "MB", "GB", "TB"];
1847
- let value = bytes;
1848
- let unit = -1;
1849
- do {
1850
- value /= 1024;
1851
- unit += 1;
1852
- } while (value >= 1024 && unit < units.length - 1);
1853
- return `${value >= 10 ? Math.round(value) : value.toFixed(1)} ${units[unit] ?? "TB"}`;
1854
- }
1855
1876
  function UploadProgressListImpl({
1856
1877
  uploads,
1857
1878
  onDismiss,
@@ -2413,7 +2434,6 @@ export {
2413
2434
  VolumeXIcon,
2414
2435
  XIcon,
2415
2436
  cn,
2416
- formatFileSize,
2417
2437
  useMediaDropzone
2418
2438
  };
2419
2439
  //# sourceMappingURL=react.js.map