@ai-matrx/media 0.5.12 → 0.6.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/CHANGELOG.md +31 -0
- package/dist/core.cjs +76 -8
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +7 -1
- package/dist/core.d.ts +7 -1
- package/dist/core.js +76 -8
- package/dist/core.js.map +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +90 -3
- package/dist/index.d.ts +90 -3
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +86 -15
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +86 -15
- package/dist/react.js.map +1 -1
- package/package.json +2 -2
package/dist/react.js
CHANGED
|
@@ -725,7 +725,7 @@ function useMediaLoadRecovery(src, options) {
|
|
|
725
725
|
const recoverable = options?.recoverable !== false;
|
|
726
726
|
const onTerminal = options?.onTerminal;
|
|
727
727
|
const failureRef = options?.failureRef;
|
|
728
|
-
const [result, setResult] = useState3({ source: src, retryKey: 0, failed: false });
|
|
728
|
+
const [result, setResult] = useState3({ source: src, retryKey: 0, failed: false, healedSrc: null });
|
|
729
729
|
const attemptRef = useRef3(0);
|
|
730
730
|
const recoveryInFlightRef = useRef3(false);
|
|
731
731
|
useEffect3(() => {
|
|
@@ -739,7 +739,7 @@ function useMediaLoadRecovery(src, options) {
|
|
|
739
739
|
const onLoadError = (event) => {
|
|
740
740
|
if (recoveryInFlightRef.current) return;
|
|
741
741
|
if (!src || !recoverable) {
|
|
742
|
-
setResult({ source: src, retryKey: 0, failed: true });
|
|
742
|
+
setResult({ source: src, retryKey: 0, failed: true, healedSrc: null });
|
|
743
743
|
if (src) {
|
|
744
744
|
capture({
|
|
745
745
|
phase: "element-load",
|
|
@@ -770,23 +770,90 @@ function useMediaLoadRecovery(src, options) {
|
|
|
770
770
|
setResult((current) => ({
|
|
771
771
|
source: src,
|
|
772
772
|
retryKey: current.source === src ? current.retryKey + 1 : 1,
|
|
773
|
-
failed: false
|
|
773
|
+
failed: false,
|
|
774
|
+
healedSrc: null
|
|
774
775
|
}));
|
|
775
|
-
|
|
776
|
-
|
|
776
|
+
return;
|
|
777
|
+
}
|
|
778
|
+
const lane1 = {
|
|
779
|
+
lane: "session-refresh-retry",
|
|
780
|
+
outcome: attempt > 1 ? "http-error" : "unavailable",
|
|
781
|
+
ms: 0,
|
|
782
|
+
...report.status !== void 0 ? { status: report.status } : {},
|
|
783
|
+
detail: attempt > 1 ? "cookie re-minted, same durable URL retried in the element, element errored again" : "recovery declined on the first attempt (no usable session)"
|
|
784
|
+
};
|
|
785
|
+
if (!failureRef || !client.healLoadError) {
|
|
786
|
+
setResult({ source: src, retryKey: 0, failed: true, healedSrc: null });
|
|
777
787
|
capture({
|
|
778
788
|
phase: attempt > 1 ? "element-load" : "recovery",
|
|
779
789
|
mediaRef: identity(),
|
|
780
790
|
terminal: true,
|
|
781
791
|
retryOutcome: attempt > 1 ? "retried" : "not-attempted",
|
|
782
|
-
message: attempt > 1 ? "media element failed to load after the session-refresh retry" : "media load recovery declined on the first attempt (session refresh did not produce a usable session)",
|
|
792
|
+
message: (attempt > 1 ? "media element failed to load after the session-refresh retry" : "media load recovery declined on the first attempt (session refresh did not produce a usable session)") + (failureRef ? " \u2014 no heal ladder on this client (healLoadError not implemented)" : " \u2014 no durable ref supplied, so no heal lane could run"),
|
|
783
793
|
...report.status !== void 0 ? { status: report.status } : {}
|
|
784
794
|
});
|
|
785
795
|
onTerminal?.(event);
|
|
796
|
+
return;
|
|
786
797
|
}
|
|
798
|
+
const heal = client.healLoadError(failureRef, {
|
|
799
|
+
src: mintDurableSrc(src),
|
|
800
|
+
attempts: [lane1]
|
|
801
|
+
});
|
|
802
|
+
heal.then(
|
|
803
|
+
(verdict) => {
|
|
804
|
+
if (verdict.src) {
|
|
805
|
+
setResult({
|
|
806
|
+
source: src,
|
|
807
|
+
retryKey: 0,
|
|
808
|
+
failed: false,
|
|
809
|
+
healedSrc: verdict.src
|
|
810
|
+
});
|
|
811
|
+
capture({
|
|
812
|
+
phase: "heal",
|
|
813
|
+
mediaRef: identity(),
|
|
814
|
+
terminal: false,
|
|
815
|
+
healed: true,
|
|
816
|
+
healedBy: verdict.healedBy,
|
|
817
|
+
attempts: verdict.attempts,
|
|
818
|
+
diagnosis: verdict.diagnosis,
|
|
819
|
+
retryOutcome: "retried",
|
|
820
|
+
message: `HEALED (${verdict.healedBy ?? "unknown lane"}): ${verdict.summary}`,
|
|
821
|
+
...report.status !== void 0 ? { status: report.status } : {}
|
|
822
|
+
});
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
setResult({ source: src, retryKey: 0, failed: true, healedSrc: null });
|
|
826
|
+
capture({
|
|
827
|
+
phase: "heal",
|
|
828
|
+
mediaRef: identity(),
|
|
829
|
+
terminal: true,
|
|
830
|
+
healed: false,
|
|
831
|
+
attempts: verdict.attempts,
|
|
832
|
+
diagnosis: verdict.diagnosis,
|
|
833
|
+
retryOutcome: "retried",
|
|
834
|
+
message: `DEAD after ${verdict.attempts.length} lane(s): ${verdict.summary}`,
|
|
835
|
+
...report.status !== void 0 ? { status: report.status } : {}
|
|
836
|
+
});
|
|
837
|
+
onTerminal?.(event);
|
|
838
|
+
},
|
|
839
|
+
(err) => {
|
|
840
|
+
setResult({ source: src, retryKey: 0, failed: true, healedSrc: null });
|
|
841
|
+
capture({
|
|
842
|
+
phase: "heal",
|
|
843
|
+
mediaRef: identity(),
|
|
844
|
+
terminal: true,
|
|
845
|
+
healed: false,
|
|
846
|
+
attempts: [lane1],
|
|
847
|
+
diagnosis: "unknown",
|
|
848
|
+
retryOutcome: "recovery-failed",
|
|
849
|
+
message: `heal ladder threw: ${err instanceof Error ? err.message : String(err ?? "unknown error")}`
|
|
850
|
+
});
|
|
851
|
+
onTerminal?.(event);
|
|
852
|
+
}
|
|
853
|
+
);
|
|
787
854
|
},
|
|
788
855
|
(err) => {
|
|
789
|
-
setResult({ source: src, retryKey: 0, failed: true });
|
|
856
|
+
setResult({ source: src, retryKey: 0, failed: true, healedSrc: null });
|
|
790
857
|
capture({
|
|
791
858
|
phase: "session",
|
|
792
859
|
mediaRef: identity(),
|
|
@@ -801,7 +868,8 @@ function useMediaLoadRecovery(src, options) {
|
|
|
801
868
|
return {
|
|
802
869
|
retryKey: result.source === src ? result.retryKey : 0,
|
|
803
870
|
onLoadError,
|
|
804
|
-
failed: result.source === src ? result.failed : false
|
|
871
|
+
failed: result.source === src ? result.failed : false,
|
|
872
|
+
healedSrc: result.source === src ? result.healedSrc : null
|
|
805
873
|
};
|
|
806
874
|
}
|
|
807
875
|
|
|
@@ -1130,15 +1198,16 @@ function InlineMediaRef({
|
|
|
1130
1198
|
resolution && (resolution.transport === "blob" || crossOrigin && resolution.isCdn !== true)
|
|
1131
1199
|
);
|
|
1132
1200
|
const blob = useMediaBlob(needsBlob ? mediaRef : null);
|
|
1133
|
-
const
|
|
1201
|
+
const resolvedUrl = needsBlob ? blob.url : resolution?.src ?? null;
|
|
1134
1202
|
const terminalCallback = (event) => onError?.(
|
|
1135
1203
|
event
|
|
1136
1204
|
);
|
|
1137
|
-
const recovery = useMediaLoadRecovery(
|
|
1205
|
+
const recovery = useMediaLoadRecovery(resolvedUrl, {
|
|
1138
1206
|
recoverable: resolution?.recoverable !== false,
|
|
1139
1207
|
failureRef: mediaRef,
|
|
1140
1208
|
onTerminal: terminalCallback
|
|
1141
1209
|
});
|
|
1210
|
+
const url = recovery.healedSrc ?? resolvedUrl;
|
|
1142
1211
|
const blobRecovery = useMediaBlobLoadRecovery(
|
|
1143
1212
|
needsBlob ? mediaRef : null,
|
|
1144
1213
|
needsBlob ? url : null,
|
|
@@ -1533,18 +1602,19 @@ function ImageThumb({
|
|
|
1533
1602
|
blobRecovery,
|
|
1534
1603
|
fallback
|
|
1535
1604
|
}) {
|
|
1536
|
-
const { retryKey, onLoadError, failed } = useMediaLoadRecovery(url, {
|
|
1605
|
+
const { retryKey, onLoadError, failed, healedSrc } = useMediaLoadRecovery(url, {
|
|
1537
1606
|
recoverable,
|
|
1538
1607
|
failureRef: mediaRef
|
|
1539
1608
|
});
|
|
1540
1609
|
const activeRecovery = blobBacked ? { retryKey: 0, ...blobRecovery } : { retryKey, onLoadError, failed };
|
|
1610
|
+
const renderUrl = !blobBacked && healedSrc || url;
|
|
1541
1611
|
if (activeRecovery.failed) return /* @__PURE__ */ jsx4(Fragment2, { children: fallback });
|
|
1542
1612
|
return /* @__PURE__ */ jsx4(
|
|
1543
1613
|
"img",
|
|
1544
1614
|
{
|
|
1545
|
-
src:
|
|
1615
|
+
src: renderUrl,
|
|
1546
1616
|
alt,
|
|
1547
|
-
loading:
|
|
1617
|
+
loading: renderUrl.startsWith("blob:") ? "eager" : "lazy",
|
|
1548
1618
|
className: "h-full w-full object-cover",
|
|
1549
1619
|
onError: activeRecovery.onLoadError
|
|
1550
1620
|
},
|
|
@@ -1559,11 +1629,12 @@ function VideoPosterThumb({
|
|
|
1559
1629
|
blobRecovery,
|
|
1560
1630
|
fallback
|
|
1561
1631
|
}) {
|
|
1562
|
-
const { retryKey, onLoadError, failed } = useMediaLoadRecovery(url, {
|
|
1632
|
+
const { retryKey, onLoadError, failed, healedSrc } = useMediaLoadRecovery(url, {
|
|
1563
1633
|
recoverable,
|
|
1564
1634
|
failureRef: mediaRef
|
|
1565
1635
|
});
|
|
1566
1636
|
const activeRecovery = blobBacked ? { retryKey: 0, ...blobRecovery } : { retryKey, onLoadError, failed };
|
|
1637
|
+
const renderUrl = !blobBacked && healedSrc || url;
|
|
1567
1638
|
const ref = useRef5(null);
|
|
1568
1639
|
useEffect6(() => {
|
|
1569
1640
|
const v = ref.current;
|
|
@@ -1582,7 +1653,7 @@ function VideoPosterThumb({
|
|
|
1582
1653
|
"video",
|
|
1583
1654
|
{
|
|
1584
1655
|
ref,
|
|
1585
|
-
src:
|
|
1656
|
+
src: renderUrl,
|
|
1586
1657
|
className: "h-full w-full object-cover pointer-events-none",
|
|
1587
1658
|
preload: "metadata",
|
|
1588
1659
|
muted: true,
|