@ai-matrx/media 0.4.2 → 0.4.4
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/viewers.cjs +22 -117
- package/dist/viewers.cjs.map +1 -1
- package/dist/viewers.js +23 -118
- package/dist/viewers.js.map +1 -1
- package/package.json +1 -1
package/dist/viewers.js
CHANGED
|
@@ -1391,104 +1391,8 @@ function HtmlSourceView({ source, maxBytes = 1024 * 1024 }) {
|
|
|
1391
1391
|
return /* @__PURE__ */ jsx8("pre", { className: "h-full w-full overflow-auto bg-muted/10 p-4 font-mono text-xs leading-relaxed break-all whitespace-pre-wrap", children: text });
|
|
1392
1392
|
}
|
|
1393
1393
|
|
|
1394
|
-
// src/
|
|
1395
|
-
import { useEffect as useEffect6,
|
|
1396
|
-
|
|
1397
|
-
// src/types.ts
|
|
1398
|
-
function mintDurableSrc(url) {
|
|
1399
|
-
return url;
|
|
1400
|
-
}
|
|
1401
|
-
|
|
1402
|
-
// src/core/use-media-load-recovery.ts
|
|
1403
|
-
function normalizeOutcome(outcome) {
|
|
1404
|
-
return typeof outcome === "string" ? { verdict: outcome } : outcome;
|
|
1405
|
-
}
|
|
1406
|
-
var EPHEMERAL_SECRET_IDENTITY = "server:files-session-secret";
|
|
1407
|
-
function useMediaLoadRecovery(src, options) {
|
|
1408
|
-
const client = useMediaClient();
|
|
1409
|
-
const capture = useMediaFailureCapture();
|
|
1410
|
-
const recoverable = options?.recoverable !== false;
|
|
1411
|
-
const onTerminal = options?.onTerminal;
|
|
1412
|
-
const failureRef = options?.failureRef;
|
|
1413
|
-
const [result, setResult] = useState8({ source: src, retryKey: 0, failed: false });
|
|
1414
|
-
const attemptRef = useRef3(0);
|
|
1415
|
-
const recoveryInFlightRef = useRef3(false);
|
|
1416
|
-
useEffect6(() => {
|
|
1417
|
-
attemptRef.current = 0;
|
|
1418
|
-
recoveryInFlightRef.current = false;
|
|
1419
|
-
}, [src]);
|
|
1420
|
-
useLayoutEffect(() => {
|
|
1421
|
-
recoveryInFlightRef.current = false;
|
|
1422
|
-
}, [result.retryKey]);
|
|
1423
|
-
const identity = () => failureMediaIdentity(failureRef ?? null, src);
|
|
1424
|
-
const onLoadError = (event) => {
|
|
1425
|
-
if (recoveryInFlightRef.current) return;
|
|
1426
|
-
if (!src || !recoverable) {
|
|
1427
|
-
setResult({ source: src, retryKey: 0, failed: true });
|
|
1428
|
-
if (src) {
|
|
1429
|
-
capture({
|
|
1430
|
-
phase: "element-load",
|
|
1431
|
-
mediaRef: identity(),
|
|
1432
|
-
terminal: true,
|
|
1433
|
-
retryOutcome: "not-attempted",
|
|
1434
|
-
message: "media element failed to load and the source is unrecoverable (foreign/object URL \u2014 a session refresh cannot fix it)"
|
|
1435
|
-
});
|
|
1436
|
-
}
|
|
1437
|
-
onTerminal?.(event);
|
|
1438
|
-
return;
|
|
1439
|
-
}
|
|
1440
|
-
recoveryInFlightRef.current = true;
|
|
1441
|
-
attemptRef.current += 1;
|
|
1442
|
-
const attempt = attemptRef.current;
|
|
1443
|
-
client.recoverLoadError(mintDurableSrc(src), attempt).then(
|
|
1444
|
-
(outcome) => {
|
|
1445
|
-
const report = normalizeOutcome(outcome);
|
|
1446
|
-
if (report.secretSource === "ephemeral") {
|
|
1447
|
-
capture({
|
|
1448
|
-
phase: "session",
|
|
1449
|
-
mediaRef: EPHEMERAL_SECRET_IDENTITY,
|
|
1450
|
-
terminal: false,
|
|
1451
|
-
message: "server cookie secret is ephemeral \u2014 private renders will break across restarts/instances (set a persistent files-session secret on the server)"
|
|
1452
|
-
});
|
|
1453
|
-
}
|
|
1454
|
-
if (report.verdict === "retry") {
|
|
1455
|
-
setResult((current) => ({
|
|
1456
|
-
source: src,
|
|
1457
|
-
retryKey: current.source === src ? current.retryKey + 1 : 1,
|
|
1458
|
-
failed: false
|
|
1459
|
-
}));
|
|
1460
|
-
} else {
|
|
1461
|
-
setResult({ source: src, retryKey: 0, failed: true });
|
|
1462
|
-
capture({
|
|
1463
|
-
phase: attempt > 1 ? "element-load" : "recovery",
|
|
1464
|
-
mediaRef: identity(),
|
|
1465
|
-
terminal: true,
|
|
1466
|
-
retryOutcome: attempt > 1 ? "retried" : "not-attempted",
|
|
1467
|
-
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)",
|
|
1468
|
-
...report.status !== void 0 ? { status: report.status } : {}
|
|
1469
|
-
});
|
|
1470
|
-
onTerminal?.(event);
|
|
1471
|
-
}
|
|
1472
|
-
},
|
|
1473
|
-
(err) => {
|
|
1474
|
-
setResult({ source: src, retryKey: 0, failed: true });
|
|
1475
|
-
capture({
|
|
1476
|
-
phase: "session",
|
|
1477
|
-
mediaRef: identity(),
|
|
1478
|
-
terminal: true,
|
|
1479
|
-
retryOutcome: "recovery-failed",
|
|
1480
|
-
message: `session recovery failed: ${err instanceof Error ? err.message : String(err ?? "unknown error")}`
|
|
1481
|
-
});
|
|
1482
|
-
onTerminal?.(event);
|
|
1483
|
-
}
|
|
1484
|
-
);
|
|
1485
|
-
};
|
|
1486
|
-
return {
|
|
1487
|
-
retryKey: result.source === src ? result.retryKey : 0,
|
|
1488
|
-
onLoadError,
|
|
1489
|
-
failed: result.source === src ? result.failed : false
|
|
1490
|
-
};
|
|
1491
|
-
}
|
|
1394
|
+
// src/viewers/svg-viewer.tsx
|
|
1395
|
+
import { useEffect as useEffect6, useState as useState8 } from "react";
|
|
1492
1396
|
|
|
1493
1397
|
// src/viewers/transparency-grid.ts
|
|
1494
1398
|
var TRANSPARENCY_GRID_STYLE = {
|
|
@@ -1524,30 +1428,33 @@ function SvgViewer(props) {
|
|
|
1524
1428
|
);
|
|
1525
1429
|
}
|
|
1526
1430
|
function SvgRenderedView({ source, fileName }) {
|
|
1527
|
-
const
|
|
1528
|
-
const
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1431
|
+
const fromClient = useMediaBlob(source.kind === "ref" ? source.ref : null);
|
|
1432
|
+
const [normalizedUrl, setNormalizedUrl] = useState8(null);
|
|
1433
|
+
useEffect6(() => {
|
|
1434
|
+
const blob = fromClient.blob;
|
|
1435
|
+
if (!blob || blob.type === "image/svg+xml") {
|
|
1436
|
+
setNormalizedUrl(null);
|
|
1437
|
+
return void 0;
|
|
1438
|
+
}
|
|
1439
|
+
const normalized = new Blob([blob], { type: "image/svg+xml" });
|
|
1440
|
+
const objectUrl = URL.createObjectURL(normalized);
|
|
1441
|
+
setNormalizedUrl(objectUrl);
|
|
1442
|
+
return () => URL.revokeObjectURL(objectUrl);
|
|
1443
|
+
}, [fromClient.blob]);
|
|
1444
|
+
const url = source.kind === "blob" ? source.url : normalizedUrl ?? fromClient.url;
|
|
1445
|
+
const loading = source.kind === "ref" && fromClient.loading;
|
|
1446
|
+
const error = source.kind === "ref" ? fromClient.error : null;
|
|
1447
|
+
if (error) {
|
|
1543
1448
|
return /* @__PURE__ */ jsx9(
|
|
1544
1449
|
ViewerError,
|
|
1545
1450
|
{
|
|
1546
1451
|
title: "SVG could not be rendered",
|
|
1452
|
+
message: error,
|
|
1547
1453
|
hint: "Switch to the Source view to inspect the markup."
|
|
1548
1454
|
}
|
|
1549
1455
|
);
|
|
1550
1456
|
}
|
|
1457
|
+
if (loading || !url) return /* @__PURE__ */ jsx9(ViewerSkeleton, { className: "flex-1" });
|
|
1551
1458
|
return /* @__PURE__ */ jsx9(
|
|
1552
1459
|
"div",
|
|
1553
1460
|
{
|
|
@@ -1558,10 +1465,8 @@ function SvgRenderedView({ source, fileName }) {
|
|
|
1558
1465
|
{
|
|
1559
1466
|
src: url,
|
|
1560
1467
|
alt: fileName,
|
|
1561
|
-
className: "max-h-full max-w-full object-contain drop-shadow-sm"
|
|
1562
|
-
|
|
1563
|
-
},
|
|
1564
|
-
retryKey
|
|
1468
|
+
className: "max-h-full max-w-full object-contain drop-shadow-sm"
|
|
1469
|
+
}
|
|
1565
1470
|
)
|
|
1566
1471
|
}
|
|
1567
1472
|
);
|