@wix/web5-core 1.63.19 → 1.63.21
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/cjs/components/ui/OptimizedImage.js +30 -12
- package/dist/cjs/components/ui/OptimizedImage.js.map +1 -1
- package/dist/cjs/context/ImageSetContext.js +234 -0
- package/dist/cjs/context/ImageSetContext.js.map +1 -0
- package/dist/cjs/image/imageSetTypes.js +108 -0
- package/dist/cjs/image/imageSetTypes.js.map +1 -0
- package/dist/cjs/index.js +18 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/answerSettledEvent.js +25 -0
- package/dist/cjs/types/answerSettledEvent.js.map +1 -0
- package/dist/cjs/types/dependencies.js.map +1 -1
- package/dist/esm/components/ui/OptimizedImage.js +21 -3
- package/dist/esm/components/ui/OptimizedImage.js.map +1 -1
- package/dist/esm/context/ImageSetContext.js +221 -0
- package/dist/esm/context/ImageSetContext.js.map +1 -0
- package/dist/esm/image/imageSetTypes.js +100 -0
- package/dist/esm/image/imageSetTypes.js.map +1 -0
- package/dist/esm/index.js +9 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/answerSettledEvent.js +21 -0
- package/dist/esm/types/answerSettledEvent.js.map +1 -0
- package/dist/esm/types/dependencies.js.map +1 -1
- package/dist/types/components/ui/OptimizedImage.d.ts +12 -0
- package/dist/types/components/ui/OptimizedImage.d.ts.map +1 -1
- package/dist/types/context/ImageSetContext.d.ts +74 -0
- package/dist/types/context/ImageSetContext.d.ts.map +1 -0
- package/dist/types/image/imageSetTypes.d.ts +185 -0
- package/dist/types/image/imageSetTypes.d.ts.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/types/answerSettledEvent.d.ts +33 -0
- package/dist/types/types/answerSettledEvent.d.ts.map +1 -0
- package/dist/types/types/dependencies.d.ts +15 -0
- package/dist/types/types/dependencies.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -8,10 +8,12 @@ var _imageBackdrop = require("../../utils/imageBackdrop");
|
|
|
8
8
|
var _linkTypes = require("../../types/link-types");
|
|
9
9
|
var _ComponentDependenciesContext = require("../../context/ComponentDependenciesContext");
|
|
10
10
|
var _useResolvedImageSources = require("../../hooks/useResolvedImageSources");
|
|
11
|
+
var _imageSetTypes = require("../../image/imageSetTypes");
|
|
11
12
|
var _jsxFileName = "/home/builduser/work/c2b6ca0b3fa984ee/packages/web5-core/dist/cjs/components/ui/OptimizedImage.tsx";
|
|
12
13
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
13
14
|
const lowResFallbackCache = new Map();
|
|
14
15
|
const OptimizedImage = exports.OptimizedImage = /*#__PURE__*/(0, _react.memo)(props => {
|
|
16
|
+
var _slot$visualMetadata, _slot$crop;
|
|
15
17
|
const {
|
|
16
18
|
alt,
|
|
17
19
|
className = '',
|
|
@@ -29,6 +31,7 @@ const OptimizedImage = exports.OptimizedImage = /*#__PURE__*/(0, _react.memo)(pr
|
|
|
29
31
|
disableResize = false,
|
|
30
32
|
imageMode = 'fit',
|
|
31
33
|
adaptiveBackdrop = false,
|
|
34
|
+
slot,
|
|
32
35
|
fallbackOnLowRes,
|
|
33
36
|
lowResThreshold = 550
|
|
34
37
|
} = props;
|
|
@@ -127,6 +130,21 @@ const OptimizedImage = exports.OptimizedImage = /*#__PURE__*/(0, _react.memo)(pr
|
|
|
127
130
|
const effectiveObjectFit = adaptiveActive ? backdrop != null && backdrop.hasBackdrop ? 'contain' : 'cover' : objectFit;
|
|
128
131
|
const effectiveImageMode = adaptiveActive ? backdrop != null && backdrop.hasBackdrop ? 'fit' : 'fill' : imageMode;
|
|
129
132
|
const adaptiveBackgroundColor = adaptiveActive && backdrop != null && backdrop.hasBackdrop ? backdrop.backgroundColor : undefined;
|
|
133
|
+
|
|
134
|
+
// A resolved slot answers the same two questions the canvas probe was asking,
|
|
135
|
+
// from the server's own decode. It wins wherever it is present.
|
|
136
|
+
//
|
|
137
|
+
// `contained` (ADR 0220) forces `contain` regardless of anything else: the
|
|
138
|
+
// server deliberately returned a crop at a different aspect than the slot
|
|
139
|
+
// asked for, so that the whole product stays in frame. Cropping it again with
|
|
140
|
+
// `cover` would undo exactly the cut it went out of its way to avoid, and the
|
|
141
|
+
// padding it leaves behind is what `backgroundColor` is for — guaranteed
|
|
142
|
+
// non-empty in that case.
|
|
143
|
+
const slotBackground = slot == null || (_slot$visualMetadata = slot.visualMetadata) == null ? void 0 : _slot$visualMetadata.background;
|
|
144
|
+
const slotIsSolid = slotBackground === 'IMAGE_BACKGROUND_SOLID';
|
|
145
|
+
const slotWantsContain = Boolean(slot == null || (_slot$crop = slot.crop) == null ? void 0 : _slot$crop.contained) || slotIsSolid;
|
|
146
|
+
const resolvedObjectFit = slot ? slotWantsContain ? 'contain' : 'cover' : effectiveObjectFit;
|
|
147
|
+
const resolvedBackgroundColor = slot ? slotWantsContain ? (0, _imageSetTypes.backdropColorOf)(slot) : undefined : adaptiveBackgroundColor;
|
|
130
148
|
(0, _react.useEffect)(() => {
|
|
131
149
|
if (!adaptiveActive) {
|
|
132
150
|
return;
|
|
@@ -345,7 +363,7 @@ const OptimizedImage = exports.OptimizedImage = /*#__PURE__*/(0, _react.memo)(pr
|
|
|
345
363
|
className: ['block', layout === 'intrinsic' ? '' : 'relative overflow-hidden', showDynamicBadge ? 'relative' : '', className].filter(Boolean).join(' '),
|
|
346
364
|
style: layout === 'intrinsic' ? undefined : {
|
|
347
365
|
minHeight: '1px',
|
|
348
|
-
backgroundColor:
|
|
366
|
+
backgroundColor: resolvedBackgroundColor
|
|
349
367
|
},
|
|
350
368
|
onClick: clickable ? onClick : undefined,
|
|
351
369
|
onKeyDown: clickable ? handleKeyDown : undefined,
|
|
@@ -355,7 +373,7 @@ const OptimizedImage = exports.OptimizedImage = /*#__PURE__*/(0, _react.memo)(pr
|
|
|
355
373
|
__self: void 0,
|
|
356
374
|
__source: {
|
|
357
375
|
fileName: _jsxFileName,
|
|
358
|
-
lineNumber:
|
|
376
|
+
lineNumber: 648,
|
|
359
377
|
columnNumber: 7
|
|
360
378
|
}
|
|
361
379
|
}, showDynamicBadge && /*#__PURE__*/_react.default.createElement("span", {
|
|
@@ -363,7 +381,7 @@ const OptimizedImage = exports.OptimizedImage = /*#__PURE__*/(0, _react.memo)(pr
|
|
|
363
381
|
__self: void 0,
|
|
364
382
|
__source: {
|
|
365
383
|
fileName: _jsxFileName,
|
|
366
|
-
lineNumber:
|
|
384
|
+
lineNumber: 670,
|
|
367
385
|
columnNumber: 11
|
|
368
386
|
}
|
|
369
387
|
}, contextualImageKey), !isLoaded && !isError && sourceIdentifier && /*#__PURE__*/_react.default.createElement("span", {
|
|
@@ -374,7 +392,7 @@ const OptimizedImage = exports.OptimizedImage = /*#__PURE__*/(0, _react.memo)(pr
|
|
|
374
392
|
__self: void 0,
|
|
375
393
|
__source: {
|
|
376
394
|
fileName: _jsxFileName,
|
|
377
|
-
lineNumber:
|
|
395
|
+
lineNumber: 675,
|
|
378
396
|
columnNumber: 11
|
|
379
397
|
}
|
|
380
398
|
}), isError && /*#__PURE__*/_react.default.createElement("span", {
|
|
@@ -384,7 +402,7 @@ const OptimizedImage = exports.OptimizedImage = /*#__PURE__*/(0, _react.memo)(pr
|
|
|
384
402
|
__self: void 0,
|
|
385
403
|
__source: {
|
|
386
404
|
fileName: _jsxFileName,
|
|
387
|
-
lineNumber:
|
|
405
|
+
lineNumber: 684,
|
|
388
406
|
columnNumber: 11
|
|
389
407
|
}
|
|
390
408
|
}, /*#__PURE__*/_react.default.createElement("span", {
|
|
@@ -392,7 +410,7 @@ const OptimizedImage = exports.OptimizedImage = /*#__PURE__*/(0, _react.memo)(pr
|
|
|
392
410
|
__self: void 0,
|
|
393
411
|
__source: {
|
|
394
412
|
fileName: _jsxFileName,
|
|
395
|
-
lineNumber:
|
|
413
|
+
lineNumber: 689,
|
|
396
414
|
columnNumber: 13
|
|
397
415
|
}
|
|
398
416
|
}, /*#__PURE__*/_react.default.createElement("svg", {
|
|
@@ -405,7 +423,7 @@ const OptimizedImage = exports.OptimizedImage = /*#__PURE__*/(0, _react.memo)(pr
|
|
|
405
423
|
__self: void 0,
|
|
406
424
|
__source: {
|
|
407
425
|
fileName: _jsxFileName,
|
|
408
|
-
lineNumber:
|
|
426
|
+
lineNumber: 690,
|
|
409
427
|
columnNumber: 15
|
|
410
428
|
}
|
|
411
429
|
}, /*#__PURE__*/_react.default.createElement("path", {
|
|
@@ -416,7 +434,7 @@ const OptimizedImage = exports.OptimizedImage = /*#__PURE__*/(0, _react.memo)(pr
|
|
|
416
434
|
__self: void 0,
|
|
417
435
|
__source: {
|
|
418
436
|
fileName: _jsxFileName,
|
|
419
|
-
lineNumber:
|
|
437
|
+
lineNumber: 698,
|
|
420
438
|
columnNumber: 17
|
|
421
439
|
}
|
|
422
440
|
})), /*#__PURE__*/_react.default.createElement("span", {
|
|
@@ -424,13 +442,13 @@ const OptimizedImage = exports.OptimizedImage = /*#__PURE__*/(0, _react.memo)(pr
|
|
|
424
442
|
__self: void 0,
|
|
425
443
|
__source: {
|
|
426
444
|
fileName: _jsxFileName,
|
|
427
|
-
lineNumber:
|
|
445
|
+
lineNumber: 705,
|
|
428
446
|
columnNumber: 15
|
|
429
447
|
}
|
|
430
448
|
}, "Failed to load image"))), imageUrl && !isError && /*#__PURE__*/_react.default.createElement("img", {
|
|
431
449
|
src: imageUrl,
|
|
432
450
|
alt: alt,
|
|
433
|
-
className: `${layout === 'intrinsic' ? 'w-full h-auto' : 'absolute inset-0 w-full h-full'} transition-opacity duration-300 ${isLoaded ? 'opacity-100' : 'opacity-0'} ${
|
|
451
|
+
className: `${layout === 'intrinsic' ? 'w-full h-auto' : 'absolute inset-0 w-full h-full'} transition-opacity duration-300 ${isLoaded ? 'opacity-100' : 'opacity-0'} ${resolvedObjectFit === 'contain' ? 'object-contain' : resolvedObjectFit === 'cover' ? 'object-cover' : resolvedObjectFit === 'fill' ? 'object-fill' : resolvedObjectFit === 'none' ? 'object-none' : resolvedObjectFit === 'scale-down' ? 'object-scale-down' : ''}`,
|
|
434
452
|
style: layout === 'intrinsic' ? {
|
|
435
453
|
width: '100%',
|
|
436
454
|
height: 'auto',
|
|
@@ -441,7 +459,7 @@ const OptimizedImage = exports.OptimizedImage = /*#__PURE__*/(0, _react.memo)(pr
|
|
|
441
459
|
inset: 0,
|
|
442
460
|
width: '100%',
|
|
443
461
|
height: '100%',
|
|
444
|
-
objectFit:
|
|
462
|
+
objectFit: resolvedObjectFit,
|
|
445
463
|
maxWidth: '100%',
|
|
446
464
|
display: 'block'
|
|
447
465
|
},
|
|
@@ -451,7 +469,7 @@ const OptimizedImage = exports.OptimizedImage = /*#__PURE__*/(0, _react.memo)(pr
|
|
|
451
469
|
__self: void 0,
|
|
452
470
|
__source: {
|
|
453
471
|
fileName: _jsxFileName,
|
|
454
|
-
lineNumber:
|
|
472
|
+
lineNumber: 711,
|
|
455
473
|
columnNumber: 11
|
|
456
474
|
}
|
|
457
475
|
})));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","_interopRequireWildcard","require","_imageUtils","_imageBackdrop","_linkTypes","_ComponentDependenciesContext","_useResolvedImageSources","_jsxFileName","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","lowResFallbackCache","Map","OptimizedImage","exports","memo","props","alt","className","quality","format","progressive","placeholderColor","objectFit","layout","onLoad","onError","onClick","clickable","imageFromText","disableResize","imageMode","adaptiveBackdrop","fallbackOnLowRes","lowResThreshold","isResolvedMode","unresolvedSource","filename","preResolvedUrl","resolvedUrl","filter","undefined","sourceIdentifier","deps","useComponentDependencies","isLoaded","setIsLoaded","useState","isError","setIsError","imageUrl","setImageUrl","isFallback","setIsFallback","backdrop","setBackdrop","isDebugImageEnabled","useDebugImageContext","dimensions","setDimensions","containerRef","useRef","observerRef","isContextualImage","useMemo","isWeb5ImageUrl","contextualImageKey","rawKey","slice","length","decodeURIComponent","trim","resolutionInputs","src","images","resolvedSources","loading","isResolutionLoading","useResolvedImageSources","resolvedSource","useEffect","logContextualImage","url","contextualTerm","imageEventType","isImageResolved","isFallbackImage","contextualImageFallback","fallbacks","fallbackImages","Math","floor","random","effectiveFilename","sourceCacheKey","normalizeImageUrl","hasResolvedSourceDimensions","width","height","isLowResResolvedAsset","cachedFallbackUrl","showDynamicBadge","adaptiveActive","adaptiveResolved","effectiveObjectFit","hasBackdrop","effectiveImageMode","adaptiveBackgroundColor","backgroundColor","token","aborted","loadBackdropAnalysis","then","result","container","current","updateDimensions","rect","getBoundingClientRect","ceil","window","ResizeObserver","observe","handleResize","addEventListener","disconnect","removeEventListener","normalizedUrl","isExternalNonWixUrl","startsWith","includes","imageFilename","match","replace","dpr","devicePixelRatio","optimizedUrl","getResizedImageUrl","handleImageLoad","img","currentTarget","naturalWidth","naturalHeight","originalImageUrl","currentSrc","console","warn","fallbackImageUrl","handleImageError","error","source","Error","isTransparentPlaceholder","placeholderStyles","background","animation","backgroundSize","handleKeyDown","key","preventDefault","createElement","Fragment","ref","Boolean","join","style","minHeight","onKeyDown","tabIndex","role","__self","__source","fileName","lineNumber","columnNumber","fill","stroke","viewBox","focusable","strokeLinecap","strokeLinejoin","strokeWidth","d","maxWidth","display","position","inset"],"sources":["../../../../src/components/ui/OptimizedImage.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, memo, useMemo } from 'react';\nimport { getResizedImageUrl, normalizeImageUrl } from '../../utils/image-utils';\nimport {\n loadBackdropAnalysis,\n type BackdropAnalysis,\n} from '../../utils/imageBackdrop';\nimport { isWeb5ImageUrl } from '../../types/link-types';\nimport { useComponentDependencies } from '../../context/ComponentDependenciesContext';\nimport type { ImageSearchFilterString } from '../../image/imageSearchFilterTypes';\nimport { useResolvedImageSources } from '../../hooks/useResolvedImageSources';\n\nconst lowResFallbackCache = new Map<string, string>();\n\ninterface OptimizedImageBaseProps {\n /** Accessible alternative text for the rendered image. */\n alt: string;\n /** Additional CSS classes applied to the outer image container. */\n className?: string;\n /** Preferred output quality for resized Wix media URLs. */\n quality?: number;\n /** Requested output format for future image delivery customization. */\n format?: 'auto' | 'webp' | 'jpg' | 'png';\n /** Enables progressive loading behavior when supported by the delivery layer. */\n progressive?: boolean;\n /** Placeholder background color shown before the image loads. */\n placeholderColor?: string;\n /** CSS object-fit behavior applied to the rendered `<img>`. */\n objectFit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';\n /** Layout strategy for the image container. */\n layout?: 'fill' | 'intrinsic';\n /** Called after the final rendered image successfully loads. */\n onLoad?: () => void;\n /** Called when the final rendered image fails to load. */\n onError?: (error: Error) => void;\n /** Click handler for interactive image surfaces. */\n onClick?: () => void;\n /** Makes the image container keyboard-focusable and clickable. */\n clickable?: boolean;\n /** Marks the source as originating from text-driven image generation for BI logging. */\n imageFromText?: boolean;\n /** Skips Wix fitted delivery URL rewriting and uses the normalized original URL directly. */\n disableResize?: boolean;\n /** CDN resize mode. 'fill' crops to exact container dimensions (sharp at slot size).\n * 'fit' (default) preserves aspect ratio. */\n imageMode?: 'fit' | 'fill';\n /**\n * Auto-pick `objectFit`/`imageMode` per image by sniffing its edges on a\n * canvas (see `imageBackdrop.ts`). Images shot on a seamless backdrop are\n * rendered `contain` with the slot painted that backdrop colour (the subject\n * is never cropped, the letterbox is invisible); full-bleed scenes fall back\n * to `cover`. Overrides `objectFit`/`imageMode` once analysis resolves; until\n * then, and on any probe/CORS failure, the passed `objectFit`/`imageMode`\n * apply. No effect for `layout=\"intrinsic\"`. */\n adaptiveBackdrop?: boolean;\n /** Full URL to a fallback image used when the primary image is considered low resolution. */\n fallbackOnLowRes?: string;\n /** Minimum acceptable width or height before low-resolution fallback is triggered. */\n lowResThreshold?: number;\n}\n\ninterface OptimizedImageWithFilenameProps {\n /** Image source to render. Supports full URLs and `web5://image/...` contextual image tokens. */\n filename: string;\n /** Optional contextual search filter used only when resolving a `web5://image/...` source. */\n filter?: ImageSearchFilterString;\n /** Mutually exclusive with `filename`; provide this only when the image URL is already resolved. */\n resolvedUrl?: never;\n}\n\ninterface OptimizedImageWithResolvedUrlProps {\n /** Already-resolved image URL. When provided, OptimizedImage skips all source resolution. */\n resolvedUrl: string;\n /** Mutually exclusive with `resolvedUrl`; use `filename` when the source still needs resolving. */\n filename?: never;\n /** Not applicable for already-resolved image URLs. */\n filter?: never;\n}\n\nexport type OptimizedImageProps = OptimizedImageBaseProps &\n (OptimizedImageWithFilenameProps | OptimizedImageWithResolvedUrlProps);\n\nexport const OptimizedImage: React.FC<OptimizedImageProps> = memo((props) => {\n const {\n alt,\n className = '',\n quality = 85,\n format = 'auto',\n progressive = true,\n placeholderColor = '#f3f4f6',\n objectFit = 'contain',\n layout = 'fill',\n onLoad,\n onError,\n onClick,\n clickable = false,\n imageFromText = false,\n disableResize = false,\n imageMode = 'fit',\n adaptiveBackdrop = false,\n fallbackOnLowRes,\n lowResThreshold = 550,\n } = props;\n void format;\n void progressive;\n\n const isResolvedMode = 'resolvedUrl' in props;\n const unresolvedSource = 'filename' in props ? props.filename ?? '' : '';\n const preResolvedUrl = 'resolvedUrl' in props ? props.resolvedUrl : '';\n const filter = 'filename' in props ? props.filter : undefined;\n const sourceIdentifier = isResolvedMode ? preResolvedUrl : unresolvedSource;\n\n const deps = useComponentDependencies();\n const [isLoaded, setIsLoaded] = useState(false);\n const [isError, setIsError] = useState(false);\n const [imageUrl, setImageUrl] = useState<string>('');\n const [isFallback, setIsFallback] = useState(false);\n // null = adaptive analysis pending (only meaningful when adaptiveBackdrop).\n const [backdrop, setBackdrop] = useState<BackdropAnalysis | null>(null);\n const isDebugImageEnabled = deps.useDebugImageContext();\n const [dimensions, setDimensions] = useState<{\n width: number;\n height: number;\n } | null>(null);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const observerRef = useRef<ResizeObserver | null>(null);\n\n const isContextualImage = useMemo(\n () =>\n !isResolvedMode &&\n !!(unresolvedSource && isWeb5ImageUrl(unresolvedSource)),\n [isResolvedMode, unresolvedSource],\n );\n\n const contextualImageKey = useMemo(() => {\n if (!isContextualImage) {\n return '';\n }\n const rawKey = unresolvedSource.slice('web5://image/'.length);\n try {\n return decodeURIComponent(rawKey).trim();\n } catch {\n return rawKey.trim();\n }\n }, [isContextualImage, unresolvedSource]);\n const resolutionInputs = useMemo(\n () =>\n isResolvedMode || !unresolvedSource\n ? []\n : [\n {\n src: unresolvedSource,\n filter,\n },\n ],\n [filter, isResolvedMode, unresolvedSource],\n );\n const { images: resolvedSources, loading: isResolutionLoading } =\n useResolvedImageSources(resolutionInputs);\n const resolvedSource = useMemo(\n () => (!isResolvedMode ? resolvedSources?.[0] ?? null : null),\n [isResolvedMode, resolvedSources],\n );\n\n useEffect(() => {\n if (\n !isContextualImage ||\n isResolvedMode ||\n isResolutionLoading ||\n resolvedSources === null\n ) {\n return;\n }\n\n deps.logContextualImage?.({\n imageUrl: resolvedSource?.url ?? '',\n contextualTerm: contextualImageKey,\n imageEventType: imageFromText\n ? 'web5_image_link_from_text'\n : 'web5_image_link',\n isImageResolved: !!resolvedSource?.url,\n isFallbackImage: false,\n });\n }, [\n contextualImageKey,\n deps,\n imageFromText,\n isContextualImage,\n isResolvedMode,\n isResolutionLoading,\n resolvedSource?.url,\n resolvedSources,\n ]);\n\n // When imageFromText contextual image resolution returns empty, use a random fallback\n const contextualImageFallback = useMemo(() => {\n if (\n !imageFromText ||\n !isContextualImage ||\n isResolutionLoading ||\n resolvedSources === null ||\n resolvedSource?.url\n ) {\n return '';\n }\n const fallbacks = deps.fallbackImages;\n if (!fallbacks || fallbacks.length === 0) {\n return '';\n }\n return fallbacks[Math.floor(Math.random() * fallbacks.length)];\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n imageFromText,\n isContextualImage,\n isResolutionLoading,\n resolvedSources,\n resolvedSource?.url,\n deps.fallbackImages,\n ]);\n\n // Log when a fallback image is used for an unresolved contextual image\n useEffect(() => {\n if (!contextualImageFallback) {\n return;\n }\n deps.logContextualImage?.({\n imageUrl: contextualImageFallback,\n contextualTerm: contextualImageKey,\n imageEventType: 'web5_image_fallback',\n isImageResolved: false,\n isFallbackImage: true,\n });\n }, [contextualImageFallback, contextualImageKey, deps]);\n\n const effectiveFilename = isResolvedMode\n ? preResolvedUrl\n : resolvedSource?.url || contextualImageFallback;\n const sourceCacheKey = useMemo(\n () =>\n effectiveFilename ? normalizeImageUrl(effectiveFilename).trim() : '',\n [effectiveFilename],\n );\n const hasResolvedSourceDimensions =\n typeof resolvedSource?.width === 'number' &&\n typeof resolvedSource?.height === 'number';\n const isLowResResolvedAsset =\n hasResolvedSourceDimensions &&\n (resolvedSource.width! < lowResThreshold ||\n resolvedSource.height! < lowResThreshold);\n const cachedFallbackUrl = useMemo(\n () => (sourceCacheKey ? lowResFallbackCache.get(sourceCacheKey) ?? '' : ''),\n [sourceCacheKey],\n );\n const showDynamicBadge = isContextualImage && isDebugImageEnabled;\n\n // Adaptive fit: probe the resolved image's edges, then map to fit/object-fit.\n // Until analysis resolves (`backdrop === null`) the displayed URL is held back\n // so we never fetch with the wrong mode and flash a re-crop. On a backdrop we\n // render `contain` (whole subject visible) and paint the slot its colour; on a\n // busy scene we `cover`. Failures resolve to `hasBackdrop: false` → `cover`.\n const adaptiveActive = adaptiveBackdrop && layout !== 'intrinsic';\n const adaptiveResolved = !adaptiveActive || backdrop !== null;\n const effectiveObjectFit = adaptiveActive\n ? backdrop?.hasBackdrop\n ? 'contain'\n : 'cover'\n : objectFit;\n const effectiveImageMode = adaptiveActive\n ? backdrop?.hasBackdrop\n ? 'fit'\n : 'fill'\n : imageMode;\n const adaptiveBackgroundColor =\n adaptiveActive && backdrop?.hasBackdrop\n ? backdrop.backgroundColor\n : undefined;\n\n useEffect(() => {\n if (!adaptiveActive) {\n return;\n }\n setBackdrop(null);\n if (\n !effectiveFilename ||\n isFallback ||\n cachedFallbackUrl ||\n (isLowResResolvedAsset && fallbackOnLowRes)\n ) {\n // No analyzable primary source → behave like a busy scene (cover).\n setBackdrop({ hasBackdrop: false });\n return;\n }\n const token = { aborted: false };\n loadBackdropAnalysis(effectiveFilename, token).then((result) => {\n if (!token.aborted) {\n setBackdrop(result);\n }\n });\n return () => {\n token.aborted = true;\n };\n }, [\n adaptiveActive,\n effectiveFilename,\n isFallback,\n cachedFallbackUrl,\n isLowResResolvedAsset,\n fallbackOnLowRes,\n ]);\n\n useEffect(() => {\n setIsLoaded(false);\n setIsError(false);\n setIsFallback(false);\n setImageUrl('');\n }, [sourceCacheKey, fallbackOnLowRes]);\n\n useEffect(() => {\n if (!sourceCacheKey || !fallbackOnLowRes) {\n return;\n }\n\n if (isLowResResolvedAsset) {\n lowResFallbackCache.set(sourceCacheKey, fallbackOnLowRes);\n setIsFallback(true);\n setImageUrl(fallbackOnLowRes);\n return;\n }\n\n if (!cachedFallbackUrl) {\n return;\n }\n\n setIsFallback(true);\n setImageUrl(cachedFallbackUrl);\n }, [\n cachedFallbackUrl,\n fallbackOnLowRes,\n isLowResResolvedAsset,\n sourceCacheKey,\n ]);\n\n // For fill layout, measure container so we can request a resized Wix image.\n useEffect(() => {\n if (layout === 'intrinsic' || disableResize) {\n return;\n }\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n const updateDimensions = () => {\n const rect = container.getBoundingClientRect();\n if (rect.width > 0 && rect.height > 0) {\n setDimensions({\n width: Math.ceil(rect.width),\n height: Math.ceil(rect.height),\n });\n }\n };\n\n updateDimensions();\n\n if ('ResizeObserver' in window) {\n observerRef.current = new ResizeObserver(() => {\n updateDimensions();\n });\n observerRef.current.observe(container);\n }\n\n const handleResize = () => updateDimensions();\n window.addEventListener('resize', handleResize);\n\n return () => {\n if (observerRef.current) {\n observerRef.current.disconnect();\n }\n window.removeEventListener('resize', handleResize);\n };\n }, [disableResize, layout]);\n\n // Intrinsic layout: use normalized URL without resize logic.\n useEffect(() => {\n if (layout !== 'intrinsic') {\n return;\n }\n if (\n !effectiveFilename ||\n isFallback ||\n cachedFallbackUrl ||\n (isLowResResolvedAsset && fallbackOnLowRes)\n ) {\n return;\n }\n\n const normalizedUrl = normalizeImageUrl(effectiveFilename);\n setImageUrl(normalizedUrl);\n }, [\n cachedFallbackUrl,\n effectiveFilename,\n isFallback,\n isLowResResolvedAsset,\n layout,\n ]);\n\n // External non-Wix URLs skip resizing; use them immediately.\n useEffect(() => {\n if (layout === 'intrinsic') {\n return;\n }\n if (\n !effectiveFilename ||\n isFallback ||\n cachedFallbackUrl ||\n (isLowResResolvedAsset && fallbackOnLowRes)\n ) {\n return;\n }\n\n const normalizedUrl = normalizeImageUrl(effectiveFilename);\n const isExternalNonWixUrl =\n (normalizedUrl.startsWith('http://') ||\n normalizedUrl.startsWith('https://')) &&\n !normalizedUrl.includes('static.wixstatic.com');\n\n if (isExternalNonWixUrl) {\n setImageUrl(normalizedUrl);\n }\n }, [\n cachedFallbackUrl,\n effectiveFilename,\n isFallback,\n isLowResResolvedAsset,\n layout,\n ]);\n\n // Explicit opt-out: use original normalized URL even in fill layouts.\n useEffect(() => {\n if (layout === 'intrinsic') {\n return;\n }\n if (\n !disableResize ||\n !effectiveFilename ||\n isFallback ||\n cachedFallbackUrl ||\n (isLowResResolvedAsset && fallbackOnLowRes)\n ) {\n return;\n }\n\n setImageUrl(normalizeImageUrl(effectiveFilename));\n }, [\n cachedFallbackUrl,\n disableResize,\n effectiveFilename,\n isFallback,\n isLowResResolvedAsset,\n layout,\n ]);\n\n // Wix/local URLs: wait for dimensions, then build a resized URL.\n useEffect(() => {\n if (layout === 'intrinsic') {\n return;\n }\n if (disableResize) {\n return;\n }\n // Hold the fetch until adaptive analysis picks fit vs fill, so we request\n // the right CDN mode once instead of fetching twice and re-cropping.\n if (!adaptiveResolved) {\n return;\n }\n if (\n !dimensions ||\n !effectiveFilename ||\n isFallback ||\n cachedFallbackUrl ||\n (isLowResResolvedAsset && fallbackOnLowRes)\n ) {\n return;\n }\n\n const normalizedUrl = normalizeImageUrl(effectiveFilename);\n const isExternalNonWixUrl =\n (normalizedUrl.startsWith('http://') ||\n normalizedUrl.startsWith('https://')) &&\n !normalizedUrl.includes('static.wixstatic.com');\n\n if (isExternalNonWixUrl) {\n return;\n }\n\n let imageFilename = effectiveFilename;\n if (normalizedUrl.includes('static.wixstatic.com')) {\n const match = normalizedUrl.match(/media\\/([^/?]+)/);\n if (match && match[1]) {\n imageFilename = match[1];\n } else {\n setImageUrl(normalizedUrl);\n return;\n }\n } else if (\n normalizedUrl.startsWith('https://static.wixstatic.com/media/')\n ) {\n imageFilename = normalizedUrl.replace(\n 'https://static.wixstatic.com/media/',\n '',\n );\n }\n\n const dpr = window.devicePixelRatio ?? 1;\n const optimizedUrl = getResizedImageUrl(\n imageFilename,\n dimensions.width * dpr,\n dimensions.height * dpr,\n { quality, imageMode: effectiveImageMode },\n );\n setImageUrl(optimizedUrl);\n }, [\n dimensions,\n cachedFallbackUrl,\n effectiveFilename,\n isFallback,\n isLowResResolvedAsset,\n layout,\n disableResize,\n quality,\n effectiveImageMode,\n adaptiveResolved,\n ]);\n\n const handleImageLoad = (e: React.SyntheticEvent<HTMLImageElement>) => {\n const img = e.currentTarget;\n\n if (\n fallbackOnLowRes &&\n !isFallback &&\n !hasResolvedSourceDimensions &&\n (img.naturalWidth < lowResThreshold ||\n img.naturalHeight < lowResThreshold)\n ) {\n const originalImageUrl =\n img.currentSrc || imageUrl || effectiveFilename || sourceIdentifier;\n\n if (sourceCacheKey) {\n lowResFallbackCache.set(sourceCacheKey, fallbackOnLowRes);\n }\n\n setIsFallback(true);\n setImageUrl(fallbackOnLowRes);\n setIsLoaded(false);\n\n console.warn('OptimizedImage applied a low-res fallback image.', {\n originalImageUrl,\n fallbackImageUrl: fallbackOnLowRes,\n naturalWidth: img.naturalWidth,\n naturalHeight: img.naturalHeight,\n lowResThreshold,\n });\n\n deps.logContextualImage?.({\n imageUrl: fallbackOnLowRes,\n contextualTerm: contextualImageKey,\n imageEventType: 'web5_image_fallback',\n isImageResolved: true,\n isFallbackImage: true,\n });\n return;\n }\n\n setIsLoaded(true);\n onLoad?.();\n };\n\n const handleImageError = () => {\n setIsError(true);\n console.error('Failed to load image:', {\n source: sourceIdentifier,\n imageUrl,\n alt,\n });\n onError?.(new Error(`Failed to load image: ${sourceIdentifier}`));\n };\n\n const isTransparentPlaceholder = placeholderColor === 'transparent';\n const placeholderStyles = isTransparentPlaceholder\n ? {\n background: 'transparent',\n animation: 'none',\n }\n : {\n background: `linear-gradient(90deg, ${placeholderColor} 0%, #e5e7eb 50%, ${placeholderColor} 100%)`,\n backgroundSize: '200% 100%',\n animation: 'shimmer 2s infinite ease-in-out',\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (onClick && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n onClick();\n }\n };\n\n return (\n <>\n <span\n ref={containerRef}\n className={[\n 'block',\n layout === 'intrinsic' ? '' : 'relative overflow-hidden',\n showDynamicBadge ? 'relative' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n style={\n layout === 'intrinsic'\n ? undefined\n : { minHeight: '1px', backgroundColor: adaptiveBackgroundColor }\n }\n onClick={clickable ? onClick : undefined}\n onKeyDown={clickable ? handleKeyDown : undefined}\n tabIndex={clickable ? 0 : undefined}\n role={clickable ? 'button' : undefined}\n aria-label={clickable ? alt : undefined}\n >\n {showDynamicBadge && (\n <span className=\"absolute left-2 top-2 z-10 rounded bg-blue-600/90 px-2 py-1 text-[10px] font-semibold tracking-wide text-white shadow block\">\n {contextualImageKey}\n </span>\n )}\n {!isLoaded && !isError && sourceIdentifier && (\n <span\n className=\"absolute inset-0 rounded block\"\n style={placeholderStyles}\n role=\"status\"\n aria-label=\"Loading image\"\n />\n )}\n\n {isError && (\n <span\n className=\"absolute inset-0 flex items-center justify-center bg-gray-100 text-gray-500 rounded block\"\n role=\"alert\"\n aria-live=\"assertive\"\n >\n <span className=\"text-center p-4 block\">\n <svg\n className=\"w-8 h-8 mx-auto mb-2 text-gray-400\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n <span className=\"text-xs block\">Failed to load image</span>\n </span>\n </span>\n )}\n\n {imageUrl && !isError && (\n <img\n src={imageUrl}\n alt={alt}\n className={`${\n layout === 'intrinsic'\n ? 'w-full h-auto'\n : 'absolute inset-0 w-full h-full'\n } transition-opacity duration-300 ${\n isLoaded ? 'opacity-100' : 'opacity-0'\n } ${\n effectiveObjectFit === 'contain'\n ? 'object-contain'\n : effectiveObjectFit === 'cover'\n ? 'object-cover'\n : effectiveObjectFit === 'fill'\n ? 'object-fill'\n : effectiveObjectFit === 'none'\n ? 'object-none'\n : effectiveObjectFit === 'scale-down'\n ? 'object-scale-down'\n : ''\n }`}\n style={\n layout === 'intrinsic'\n ? {\n width: '100%',\n height: 'auto',\n maxWidth: '100%',\n display: 'block',\n }\n : {\n position: 'absolute',\n inset: 0,\n width: '100%',\n height: '100%',\n objectFit: effectiveObjectFit,\n maxWidth: '100%',\n display: 'block',\n }\n }\n onLoad={handleImageLoad}\n onError={handleImageError}\n loading={imageUrl.startsWith('data:') ? 'eager' : 'lazy'}\n />\n )}\n </span>\n </>\n );\n});\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireWildcard","require","_imageUtils","_imageBackdrop","_linkTypes","_ComponentDependenciesContext","_useResolvedImageSources","_imageSetTypes","_jsxFileName","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","lowResFallbackCache","Map","OptimizedImage","exports","memo","props","_slot$visualMetadata","_slot$crop","alt","className","quality","format","progressive","placeholderColor","objectFit","layout","onLoad","onError","onClick","clickable","imageFromText","disableResize","imageMode","adaptiveBackdrop","slot","fallbackOnLowRes","lowResThreshold","isResolvedMode","unresolvedSource","filename","preResolvedUrl","resolvedUrl","filter","undefined","sourceIdentifier","deps","useComponentDependencies","isLoaded","setIsLoaded","useState","isError","setIsError","imageUrl","setImageUrl","isFallback","setIsFallback","backdrop","setBackdrop","isDebugImageEnabled","useDebugImageContext","dimensions","setDimensions","containerRef","useRef","observerRef","isContextualImage","useMemo","isWeb5ImageUrl","contextualImageKey","rawKey","slice","length","decodeURIComponent","trim","resolutionInputs","src","images","resolvedSources","loading","isResolutionLoading","useResolvedImageSources","resolvedSource","useEffect","logContextualImage","url","contextualTerm","imageEventType","isImageResolved","isFallbackImage","contextualImageFallback","fallbacks","fallbackImages","Math","floor","random","effectiveFilename","sourceCacheKey","normalizeImageUrl","hasResolvedSourceDimensions","width","height","isLowResResolvedAsset","cachedFallbackUrl","showDynamicBadge","adaptiveActive","adaptiveResolved","effectiveObjectFit","hasBackdrop","effectiveImageMode","adaptiveBackgroundColor","backgroundColor","slotBackground","visualMetadata","background","slotIsSolid","slotWantsContain","Boolean","crop","contained","resolvedObjectFit","resolvedBackgroundColor","backdropColorOf","token","aborted","loadBackdropAnalysis","then","result","container","current","updateDimensions","rect","getBoundingClientRect","ceil","window","ResizeObserver","observe","handleResize","addEventListener","disconnect","removeEventListener","normalizedUrl","isExternalNonWixUrl","startsWith","includes","imageFilename","match","replace","dpr","devicePixelRatio","optimizedUrl","getResizedImageUrl","handleImageLoad","img","currentTarget","naturalWidth","naturalHeight","originalImageUrl","currentSrc","console","warn","fallbackImageUrl","handleImageError","error","source","Error","isTransparentPlaceholder","placeholderStyles","animation","backgroundSize","handleKeyDown","key","preventDefault","createElement","Fragment","ref","join","style","minHeight","onKeyDown","tabIndex","role","__self","__source","fileName","lineNumber","columnNumber","fill","stroke","viewBox","focusable","strokeLinecap","strokeLinejoin","strokeWidth","d","maxWidth","display","position","inset"],"sources":["../../../../src/components/ui/OptimizedImage.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, memo, useMemo } from 'react';\nimport { getResizedImageUrl, normalizeImageUrl } from '../../utils/image-utils';\nimport {\n loadBackdropAnalysis,\n type BackdropAnalysis,\n} from '../../utils/imageBackdrop';\nimport { isWeb5ImageUrl } from '../../types/link-types';\nimport { useComponentDependencies } from '../../context/ComponentDependenciesContext';\nimport type { ImageSearchFilterString } from '../../image/imageSearchFilterTypes';\nimport { useResolvedImageSources } from '../../hooks/useResolvedImageSources';\nimport {\n backdropColorOf,\n type ResolvedImageSlot,\n} from '../../image/imageSetTypes';\n\nconst lowResFallbackCache = new Map<string, string>();\n\ninterface OptimizedImageBaseProps {\n /** Accessible alternative text for the rendered image. */\n alt: string;\n /** Additional CSS classes applied to the outer image container. */\n className?: string;\n /** Preferred output quality for resized Wix media URLs. */\n quality?: number;\n /** Requested output format for future image delivery customization. */\n format?: 'auto' | 'webp' | 'jpg' | 'png';\n /** Enables progressive loading behavior when supported by the delivery layer. */\n progressive?: boolean;\n /** Placeholder background color shown before the image loads. */\n placeholderColor?: string;\n /** CSS object-fit behavior applied to the rendered `<img>`. */\n objectFit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';\n /** Layout strategy for the image container. */\n layout?: 'fill' | 'intrinsic';\n /** Called after the final rendered image successfully loads. */\n onLoad?: () => void;\n /** Called when the final rendered image fails to load. */\n onError?: (error: Error) => void;\n /** Click handler for interactive image surfaces. */\n onClick?: () => void;\n /** Makes the image container keyboard-focusable and clickable. */\n clickable?: boolean;\n /** Marks the source as originating from text-driven image generation for BI logging. */\n imageFromText?: boolean;\n /** Skips Wix fitted delivery URL rewriting and uses the normalized original URL directly. */\n disableResize?: boolean;\n /** CDN resize mode. 'fill' crops to exact container dimensions (sharp at slot size).\n * 'fit' (default) preserves aspect ratio. */\n imageMode?: 'fit' | 'fill';\n /**\n * Auto-pick `objectFit`/`imageMode` per image by sniffing its edges on a\n * canvas (see `imageBackdrop.ts`). Images shot on a seamless backdrop are\n * rendered `contain` with the slot painted that backdrop colour (the subject\n * is never cropped, the letterbox is invisible); full-bleed scenes fall back\n * to `cover`. Overrides `objectFit`/`imageMode` once analysis resolves; until\n * then, and on any probe/CORS failure, the passed `objectFit`/`imageMode`\n * apply. No effect for `layout=\"intrinsic\"`. */\n adaptiveBackdrop?: boolean;\n /**\n * A slot resolved by `ResolveImageSet` (ADR 0221). Supplying it makes the\n * server's own decode authoritative over `adaptiveBackdrop`'s canvas probe:\n * fit comes from `visualMetadata.background` and the backdrop colour from\n * `backgroundColor` (falling back to the dominant swatch for a scene), so no\n * pixel is read back, no CORS is needed and nothing is guessed.\n *\n * Pair it with `resolvedUrl={slot.imageUrl}` and `disableResize` — the URL\n * already carries the crop and the render size.\n */\n slot?: ResolvedImageSlot;\n /** Full URL to a fallback image used when the primary image is considered low resolution. */\n fallbackOnLowRes?: string;\n /** Minimum acceptable width or height before low-resolution fallback is triggered. */\n lowResThreshold?: number;\n}\n\ninterface OptimizedImageWithFilenameProps {\n /** Image source to render. Supports full URLs and `web5://image/...` contextual image tokens. */\n filename: string;\n /** Optional contextual search filter used only when resolving a `web5://image/...` source. */\n filter?: ImageSearchFilterString;\n /** Mutually exclusive with `filename`; provide this only when the image URL is already resolved. */\n resolvedUrl?: never;\n}\n\ninterface OptimizedImageWithResolvedUrlProps {\n /** Already-resolved image URL. When provided, OptimizedImage skips all source resolution. */\n resolvedUrl: string;\n /** Mutually exclusive with `resolvedUrl`; use `filename` when the source still needs resolving. */\n filename?: never;\n /** Not applicable for already-resolved image URLs. */\n filter?: never;\n}\n\nexport type OptimizedImageProps = OptimizedImageBaseProps &\n (OptimizedImageWithFilenameProps | OptimizedImageWithResolvedUrlProps);\n\nexport const OptimizedImage: React.FC<OptimizedImageProps> = memo((props) => {\n const {\n alt,\n className = '',\n quality = 85,\n format = 'auto',\n progressive = true,\n placeholderColor = '#f3f4f6',\n objectFit = 'contain',\n layout = 'fill',\n onLoad,\n onError,\n onClick,\n clickable = false,\n imageFromText = false,\n disableResize = false,\n imageMode = 'fit',\n adaptiveBackdrop = false,\n slot,\n fallbackOnLowRes,\n lowResThreshold = 550,\n } = props;\n void format;\n void progressive;\n\n const isResolvedMode = 'resolvedUrl' in props;\n const unresolvedSource = 'filename' in props ? props.filename ?? '' : '';\n const preResolvedUrl = 'resolvedUrl' in props ? props.resolvedUrl : '';\n const filter = 'filename' in props ? props.filter : undefined;\n const sourceIdentifier = isResolvedMode ? preResolvedUrl : unresolvedSource;\n\n const deps = useComponentDependencies();\n const [isLoaded, setIsLoaded] = useState(false);\n const [isError, setIsError] = useState(false);\n const [imageUrl, setImageUrl] = useState<string>('');\n const [isFallback, setIsFallback] = useState(false);\n // null = adaptive analysis pending (only meaningful when adaptiveBackdrop).\n const [backdrop, setBackdrop] = useState<BackdropAnalysis | null>(null);\n const isDebugImageEnabled = deps.useDebugImageContext();\n const [dimensions, setDimensions] = useState<{\n width: number;\n height: number;\n } | null>(null);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const observerRef = useRef<ResizeObserver | null>(null);\n\n const isContextualImage = useMemo(\n () =>\n !isResolvedMode &&\n !!(unresolvedSource && isWeb5ImageUrl(unresolvedSource)),\n [isResolvedMode, unresolvedSource],\n );\n\n const contextualImageKey = useMemo(() => {\n if (!isContextualImage) {\n return '';\n }\n const rawKey = unresolvedSource.slice('web5://image/'.length);\n try {\n return decodeURIComponent(rawKey).trim();\n } catch {\n return rawKey.trim();\n }\n }, [isContextualImage, unresolvedSource]);\n const resolutionInputs = useMemo(\n () =>\n isResolvedMode || !unresolvedSource\n ? []\n : [\n {\n src: unresolvedSource,\n filter,\n },\n ],\n [filter, isResolvedMode, unresolvedSource],\n );\n const { images: resolvedSources, loading: isResolutionLoading } =\n useResolvedImageSources(resolutionInputs);\n const resolvedSource = useMemo(\n () => (!isResolvedMode ? resolvedSources?.[0] ?? null : null),\n [isResolvedMode, resolvedSources],\n );\n\n useEffect(() => {\n if (\n !isContextualImage ||\n isResolvedMode ||\n isResolutionLoading ||\n resolvedSources === null\n ) {\n return;\n }\n\n deps.logContextualImage?.({\n imageUrl: resolvedSource?.url ?? '',\n contextualTerm: contextualImageKey,\n imageEventType: imageFromText\n ? 'web5_image_link_from_text'\n : 'web5_image_link',\n isImageResolved: !!resolvedSource?.url,\n isFallbackImage: false,\n });\n }, [\n contextualImageKey,\n deps,\n imageFromText,\n isContextualImage,\n isResolvedMode,\n isResolutionLoading,\n resolvedSource?.url,\n resolvedSources,\n ]);\n\n // When imageFromText contextual image resolution returns empty, use a random fallback\n const contextualImageFallback = useMemo(() => {\n if (\n !imageFromText ||\n !isContextualImage ||\n isResolutionLoading ||\n resolvedSources === null ||\n resolvedSource?.url\n ) {\n return '';\n }\n const fallbacks = deps.fallbackImages;\n if (!fallbacks || fallbacks.length === 0) {\n return '';\n }\n return fallbacks[Math.floor(Math.random() * fallbacks.length)];\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n imageFromText,\n isContextualImage,\n isResolutionLoading,\n resolvedSources,\n resolvedSource?.url,\n deps.fallbackImages,\n ]);\n\n // Log when a fallback image is used for an unresolved contextual image\n useEffect(() => {\n if (!contextualImageFallback) {\n return;\n }\n deps.logContextualImage?.({\n imageUrl: contextualImageFallback,\n contextualTerm: contextualImageKey,\n imageEventType: 'web5_image_fallback',\n isImageResolved: false,\n isFallbackImage: true,\n });\n }, [contextualImageFallback, contextualImageKey, deps]);\n\n const effectiveFilename = isResolvedMode\n ? preResolvedUrl\n : resolvedSource?.url || contextualImageFallback;\n const sourceCacheKey = useMemo(\n () =>\n effectiveFilename ? normalizeImageUrl(effectiveFilename).trim() : '',\n [effectiveFilename],\n );\n const hasResolvedSourceDimensions =\n typeof resolvedSource?.width === 'number' &&\n typeof resolvedSource?.height === 'number';\n const isLowResResolvedAsset =\n hasResolvedSourceDimensions &&\n (resolvedSource.width! < lowResThreshold ||\n resolvedSource.height! < lowResThreshold);\n const cachedFallbackUrl = useMemo(\n () => (sourceCacheKey ? lowResFallbackCache.get(sourceCacheKey) ?? '' : ''),\n [sourceCacheKey],\n );\n const showDynamicBadge = isContextualImage && isDebugImageEnabled;\n\n // Adaptive fit: probe the resolved image's edges, then map to fit/object-fit.\n // Until analysis resolves (`backdrop === null`) the displayed URL is held back\n // so we never fetch with the wrong mode and flash a re-crop. On a backdrop we\n // render `contain` (whole subject visible) and paint the slot its colour; on a\n // busy scene we `cover`. Failures resolve to `hasBackdrop: false` → `cover`.\n const adaptiveActive = adaptiveBackdrop && layout !== 'intrinsic';\n const adaptiveResolved = !adaptiveActive || backdrop !== null;\n const effectiveObjectFit = adaptiveActive\n ? backdrop?.hasBackdrop\n ? 'contain'\n : 'cover'\n : objectFit;\n const effectiveImageMode = adaptiveActive\n ? backdrop?.hasBackdrop\n ? 'fit'\n : 'fill'\n : imageMode;\n const adaptiveBackgroundColor =\n adaptiveActive && backdrop?.hasBackdrop\n ? backdrop.backgroundColor\n : undefined;\n\n // A resolved slot answers the same two questions the canvas probe was asking,\n // from the server's own decode. It wins wherever it is present.\n //\n // `contained` (ADR 0220) forces `contain` regardless of anything else: the\n // server deliberately returned a crop at a different aspect than the slot\n // asked for, so that the whole product stays in frame. Cropping it again with\n // `cover` would undo exactly the cut it went out of its way to avoid, and the\n // padding it leaves behind is what `backgroundColor` is for — guaranteed\n // non-empty in that case.\n const slotBackground = slot?.visualMetadata?.background;\n const slotIsSolid = slotBackground === 'IMAGE_BACKGROUND_SOLID';\n const slotWantsContain = Boolean(slot?.crop?.contained) || slotIsSolid;\n const resolvedObjectFit = slot\n ? slotWantsContain\n ? 'contain'\n : 'cover'\n : effectiveObjectFit;\n const resolvedBackgroundColor = slot\n ? slotWantsContain\n ? backdropColorOf(slot)\n : undefined\n : adaptiveBackgroundColor;\n\n useEffect(() => {\n if (!adaptiveActive) {\n return;\n }\n setBackdrop(null);\n if (\n !effectiveFilename ||\n isFallback ||\n cachedFallbackUrl ||\n (isLowResResolvedAsset && fallbackOnLowRes)\n ) {\n // No analyzable primary source → behave like a busy scene (cover).\n setBackdrop({ hasBackdrop: false });\n return;\n }\n const token = { aborted: false };\n loadBackdropAnalysis(effectiveFilename, token).then((result) => {\n if (!token.aborted) {\n setBackdrop(result);\n }\n });\n return () => {\n token.aborted = true;\n };\n }, [\n adaptiveActive,\n effectiveFilename,\n isFallback,\n cachedFallbackUrl,\n isLowResResolvedAsset,\n fallbackOnLowRes,\n ]);\n\n useEffect(() => {\n setIsLoaded(false);\n setIsError(false);\n setIsFallback(false);\n setImageUrl('');\n }, [sourceCacheKey, fallbackOnLowRes]);\n\n useEffect(() => {\n if (!sourceCacheKey || !fallbackOnLowRes) {\n return;\n }\n\n if (isLowResResolvedAsset) {\n lowResFallbackCache.set(sourceCacheKey, fallbackOnLowRes);\n setIsFallback(true);\n setImageUrl(fallbackOnLowRes);\n return;\n }\n\n if (!cachedFallbackUrl) {\n return;\n }\n\n setIsFallback(true);\n setImageUrl(cachedFallbackUrl);\n }, [\n cachedFallbackUrl,\n fallbackOnLowRes,\n isLowResResolvedAsset,\n sourceCacheKey,\n ]);\n\n // For fill layout, measure container so we can request a resized Wix image.\n useEffect(() => {\n if (layout === 'intrinsic' || disableResize) {\n return;\n }\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n const updateDimensions = () => {\n const rect = container.getBoundingClientRect();\n if (rect.width > 0 && rect.height > 0) {\n setDimensions({\n width: Math.ceil(rect.width),\n height: Math.ceil(rect.height),\n });\n }\n };\n\n updateDimensions();\n\n if ('ResizeObserver' in window) {\n observerRef.current = new ResizeObserver(() => {\n updateDimensions();\n });\n observerRef.current.observe(container);\n }\n\n const handleResize = () => updateDimensions();\n window.addEventListener('resize', handleResize);\n\n return () => {\n if (observerRef.current) {\n observerRef.current.disconnect();\n }\n window.removeEventListener('resize', handleResize);\n };\n }, [disableResize, layout]);\n\n // Intrinsic layout: use normalized URL without resize logic.\n useEffect(() => {\n if (layout !== 'intrinsic') {\n return;\n }\n if (\n !effectiveFilename ||\n isFallback ||\n cachedFallbackUrl ||\n (isLowResResolvedAsset && fallbackOnLowRes)\n ) {\n return;\n }\n\n const normalizedUrl = normalizeImageUrl(effectiveFilename);\n setImageUrl(normalizedUrl);\n }, [\n cachedFallbackUrl,\n effectiveFilename,\n isFallback,\n isLowResResolvedAsset,\n layout,\n ]);\n\n // External non-Wix URLs skip resizing; use them immediately.\n useEffect(() => {\n if (layout === 'intrinsic') {\n return;\n }\n if (\n !effectiveFilename ||\n isFallback ||\n cachedFallbackUrl ||\n (isLowResResolvedAsset && fallbackOnLowRes)\n ) {\n return;\n }\n\n const normalizedUrl = normalizeImageUrl(effectiveFilename);\n const isExternalNonWixUrl =\n (normalizedUrl.startsWith('http://') ||\n normalizedUrl.startsWith('https://')) &&\n !normalizedUrl.includes('static.wixstatic.com');\n\n if (isExternalNonWixUrl) {\n setImageUrl(normalizedUrl);\n }\n }, [\n cachedFallbackUrl,\n effectiveFilename,\n isFallback,\n isLowResResolvedAsset,\n layout,\n ]);\n\n // Explicit opt-out: use original normalized URL even in fill layouts.\n useEffect(() => {\n if (layout === 'intrinsic') {\n return;\n }\n if (\n !disableResize ||\n !effectiveFilename ||\n isFallback ||\n cachedFallbackUrl ||\n (isLowResResolvedAsset && fallbackOnLowRes)\n ) {\n return;\n }\n\n setImageUrl(normalizeImageUrl(effectiveFilename));\n }, [\n cachedFallbackUrl,\n disableResize,\n effectiveFilename,\n isFallback,\n isLowResResolvedAsset,\n layout,\n ]);\n\n // Wix/local URLs: wait for dimensions, then build a resized URL.\n useEffect(() => {\n if (layout === 'intrinsic') {\n return;\n }\n if (disableResize) {\n return;\n }\n // Hold the fetch until adaptive analysis picks fit vs fill, so we request\n // the right CDN mode once instead of fetching twice and re-cropping.\n if (!adaptiveResolved) {\n return;\n }\n if (\n !dimensions ||\n !effectiveFilename ||\n isFallback ||\n cachedFallbackUrl ||\n (isLowResResolvedAsset && fallbackOnLowRes)\n ) {\n return;\n }\n\n const normalizedUrl = normalizeImageUrl(effectiveFilename);\n const isExternalNonWixUrl =\n (normalizedUrl.startsWith('http://') ||\n normalizedUrl.startsWith('https://')) &&\n !normalizedUrl.includes('static.wixstatic.com');\n\n if (isExternalNonWixUrl) {\n return;\n }\n\n let imageFilename = effectiveFilename;\n if (normalizedUrl.includes('static.wixstatic.com')) {\n const match = normalizedUrl.match(/media\\/([^/?]+)/);\n if (match && match[1]) {\n imageFilename = match[1];\n } else {\n setImageUrl(normalizedUrl);\n return;\n }\n } else if (\n normalizedUrl.startsWith('https://static.wixstatic.com/media/')\n ) {\n imageFilename = normalizedUrl.replace(\n 'https://static.wixstatic.com/media/',\n '',\n );\n }\n\n const dpr = window.devicePixelRatio ?? 1;\n const optimizedUrl = getResizedImageUrl(\n imageFilename,\n dimensions.width * dpr,\n dimensions.height * dpr,\n { quality, imageMode: effectiveImageMode },\n );\n setImageUrl(optimizedUrl);\n }, [\n dimensions,\n cachedFallbackUrl,\n effectiveFilename,\n isFallback,\n isLowResResolvedAsset,\n layout,\n disableResize,\n quality,\n effectiveImageMode,\n adaptiveResolved,\n ]);\n\n const handleImageLoad = (e: React.SyntheticEvent<HTMLImageElement>) => {\n const img = e.currentTarget;\n\n if (\n fallbackOnLowRes &&\n !isFallback &&\n !hasResolvedSourceDimensions &&\n (img.naturalWidth < lowResThreshold ||\n img.naturalHeight < lowResThreshold)\n ) {\n const originalImageUrl =\n img.currentSrc || imageUrl || effectiveFilename || sourceIdentifier;\n\n if (sourceCacheKey) {\n lowResFallbackCache.set(sourceCacheKey, fallbackOnLowRes);\n }\n\n setIsFallback(true);\n setImageUrl(fallbackOnLowRes);\n setIsLoaded(false);\n\n console.warn('OptimizedImage applied a low-res fallback image.', {\n originalImageUrl,\n fallbackImageUrl: fallbackOnLowRes,\n naturalWidth: img.naturalWidth,\n naturalHeight: img.naturalHeight,\n lowResThreshold,\n });\n\n deps.logContextualImage?.({\n imageUrl: fallbackOnLowRes,\n contextualTerm: contextualImageKey,\n imageEventType: 'web5_image_fallback',\n isImageResolved: true,\n isFallbackImage: true,\n });\n return;\n }\n\n setIsLoaded(true);\n onLoad?.();\n };\n\n const handleImageError = () => {\n setIsError(true);\n console.error('Failed to load image:', {\n source: sourceIdentifier,\n imageUrl,\n alt,\n });\n onError?.(new Error(`Failed to load image: ${sourceIdentifier}`));\n };\n\n const isTransparentPlaceholder = placeholderColor === 'transparent';\n const placeholderStyles = isTransparentPlaceholder\n ? {\n background: 'transparent',\n animation: 'none',\n }\n : {\n background: `linear-gradient(90deg, ${placeholderColor} 0%, #e5e7eb 50%, ${placeholderColor} 100%)`,\n backgroundSize: '200% 100%',\n animation: 'shimmer 2s infinite ease-in-out',\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (onClick && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n onClick();\n }\n };\n\n return (\n <>\n <span\n ref={containerRef}\n className={[\n 'block',\n layout === 'intrinsic' ? '' : 'relative overflow-hidden',\n showDynamicBadge ? 'relative' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n style={\n layout === 'intrinsic'\n ? undefined\n : { minHeight: '1px', backgroundColor: resolvedBackgroundColor }\n }\n onClick={clickable ? onClick : undefined}\n onKeyDown={clickable ? handleKeyDown : undefined}\n tabIndex={clickable ? 0 : undefined}\n role={clickable ? 'button' : undefined}\n aria-label={clickable ? alt : undefined}\n >\n {showDynamicBadge && (\n <span className=\"absolute left-2 top-2 z-10 rounded bg-blue-600/90 px-2 py-1 text-[10px] font-semibold tracking-wide text-white shadow block\">\n {contextualImageKey}\n </span>\n )}\n {!isLoaded && !isError && sourceIdentifier && (\n <span\n className=\"absolute inset-0 rounded block\"\n style={placeholderStyles}\n role=\"status\"\n aria-label=\"Loading image\"\n />\n )}\n\n {isError && (\n <span\n className=\"absolute inset-0 flex items-center justify-center bg-gray-100 text-gray-500 rounded block\"\n role=\"alert\"\n aria-live=\"assertive\"\n >\n <span className=\"text-center p-4 block\">\n <svg\n className=\"w-8 h-8 mx-auto mb-2 text-gray-400\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n <span className=\"text-xs block\">Failed to load image</span>\n </span>\n </span>\n )}\n\n {imageUrl && !isError && (\n <img\n src={imageUrl}\n alt={alt}\n className={`${\n layout === 'intrinsic'\n ? 'w-full h-auto'\n : 'absolute inset-0 w-full h-full'\n } transition-opacity duration-300 ${\n isLoaded ? 'opacity-100' : 'opacity-0'\n } ${\n resolvedObjectFit === 'contain'\n ? 'object-contain'\n : resolvedObjectFit === 'cover'\n ? 'object-cover'\n : resolvedObjectFit === 'fill'\n ? 'object-fill'\n : resolvedObjectFit === 'none'\n ? 'object-none'\n : resolvedObjectFit === 'scale-down'\n ? 'object-scale-down'\n : ''\n }`}\n style={\n layout === 'intrinsic'\n ? {\n width: '100%',\n height: 'auto',\n maxWidth: '100%',\n display: 'block',\n }\n : {\n position: 'absolute',\n inset: 0,\n width: '100%',\n height: '100%',\n objectFit: resolvedObjectFit,\n maxWidth: '100%',\n display: 'block',\n }\n }\n onLoad={handleImageLoad}\n onError={handleImageError}\n loading={imageUrl.startsWith('data:') ? 'eager' : 'lazy'}\n />\n )}\n </span>\n </>\n );\n});\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.ImageSetProvider = void 0;
|
|
5
|
+
exports.useImageSetEnabled = useImageSetEnabled;
|
|
6
|
+
exports.useImageSlot = useImageSlot;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _imageSetTypes = require("../image/imageSetTypes");
|
|
9
|
+
var _jsxFileName = "/home/builduser/work/c2b6ca0b3fa984ee/packages/web5-core/dist/cjs/context/ImageSetContext.tsx";
|
|
10
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
11
|
+
/**
|
|
12
|
+
* The page-level image collector (ADR 0221).
|
|
13
|
+
*
|
|
14
|
+
* Sections declare slots; this provider resolves them together. That is the
|
|
15
|
+
* whole point: a per-component call to a set-level endpoint is a one-slot
|
|
16
|
+
* request, which throws away the page-wide assignment, the per-kind mode
|
|
17
|
+
* negotiation and the cohesion that are the only reasons the endpoint takes a
|
|
18
|
+
* list at all.
|
|
19
|
+
*
|
|
20
|
+
* The shape is deliberately one-shot per turn. Slots register during the
|
|
21
|
+
* commit that renders them, the provider flushes once on the next microtask,
|
|
22
|
+
* and a slot that registers after that flush does NOT trigger a second
|
|
23
|
+
* request — it reports `late` and the caller falls back. A page that asks
|
|
24
|
+
* twice cannot be coherent, so asking twice is not offered.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
const IDLE_STATE = {
|
|
28
|
+
status: 'unavailable'
|
|
29
|
+
};
|
|
30
|
+
const ImageSetContext = /*#__PURE__*/(0, _react.createContext)(null);
|
|
31
|
+
const ImageSetProvider = ({
|
|
32
|
+
resolveImageSet,
|
|
33
|
+
preferredMode,
|
|
34
|
+
turnId,
|
|
35
|
+
maxSlots = _imageSetTypes.MAX_IMAGE_SLOTS_PER_SET,
|
|
36
|
+
children
|
|
37
|
+
}) => {
|
|
38
|
+
// Registration is refs, not state: a slot registering must not re-render the
|
|
39
|
+
// whole tree mid-collection. Subscribers are notified explicitly once the
|
|
40
|
+
// answer lands.
|
|
41
|
+
const pending = (0, _react.useRef)(new Map());
|
|
42
|
+
const states = (0, _react.useRef)(new Map());
|
|
43
|
+
const listeners = (0, _react.useRef)(new Set());
|
|
44
|
+
const flushed = (0, _react.useRef)(false);
|
|
45
|
+
const scheduled = (0, _react.useRef)(false);
|
|
46
|
+
const notify = (0, _react.useCallback)(() => {
|
|
47
|
+
listeners.current.forEach(l => l());
|
|
48
|
+
}, []);
|
|
49
|
+
|
|
50
|
+
// A new turn retires the previous set wholesale — and this MUST happen in the
|
|
51
|
+
// render phase, not an effect. Child effects run before the parent's, so a
|
|
52
|
+
// reset in `useEffect` would fire *after* this turn's slots had registered
|
|
53
|
+
// and would wipe them, leaving the flush with nothing to send. The parent
|
|
54
|
+
// renders first, so resetting here lands before any child registers.
|
|
55
|
+
const lastTurn = (0, _react.useRef)(turnId);
|
|
56
|
+
const started = (0, _react.useRef)(false);
|
|
57
|
+
if (!started.current) {
|
|
58
|
+
started.current = true;
|
|
59
|
+
} else if (lastTurn.current !== turnId) {
|
|
60
|
+
lastTurn.current = turnId;
|
|
61
|
+
pending.current.clear();
|
|
62
|
+
states.current.clear();
|
|
63
|
+
flushed.current = false;
|
|
64
|
+
scheduled.current = false;
|
|
65
|
+
}
|
|
66
|
+
const flush = (0, _react.useCallback)(async () => {
|
|
67
|
+
scheduled.current = false;
|
|
68
|
+
if (flushed.current || !resolveImageSet) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const images = Array.from(pending.current.values());
|
|
72
|
+
if (images.length === 0) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// Everything registered before the flush goes in one request; the set is
|
|
76
|
+
// closed the moment it is sent.
|
|
77
|
+
flushed.current = true;
|
|
78
|
+
try {
|
|
79
|
+
const result = await resolveImageSet({
|
|
80
|
+
images,
|
|
81
|
+
preferredMode
|
|
82
|
+
});
|
|
83
|
+
const bySlotId = new Map();
|
|
84
|
+
// The contract guarantees same length and order, but keying by the echoed
|
|
85
|
+
// slotId means a server that ever breaks that does not silently
|
|
86
|
+
// mis-attribute someone else's photograph to this slot.
|
|
87
|
+
(result.slots ?? []).forEach((s, i) => {
|
|
88
|
+
var _images$i;
|
|
89
|
+
const id = s.slotId || ((_images$i = images[i]) == null ? void 0 : _images$i.id);
|
|
90
|
+
if (id) {
|
|
91
|
+
bySlotId.set(id, s);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
images.forEach(req => {
|
|
95
|
+
const slot = bySlotId.get(req.id);
|
|
96
|
+
states.current.set(req.id, {
|
|
97
|
+
status: slot ? 'resolved' : 'failed',
|
|
98
|
+
slot,
|
|
99
|
+
mode: result.mode
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
} catch {
|
|
103
|
+
// A failed set is not a broken page: every slot falls back to whatever it
|
|
104
|
+
// rendered before.
|
|
105
|
+
images.forEach(req => {
|
|
106
|
+
states.current.set(req.id, {
|
|
107
|
+
status: 'failed'
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
notify();
|
|
112
|
+
}, [resolveImageSet, preferredMode, notify]);
|
|
113
|
+
const register = (0, _react.useCallback)(slot => {
|
|
114
|
+
var _states$current$get2;
|
|
115
|
+
if (!resolveImageSet) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (flushed.current) {
|
|
119
|
+
var _states$current$get;
|
|
120
|
+
// The set has already gone. Say so rather than open a second one.
|
|
121
|
+
if (((_states$current$get = states.current.get(slot.id)) == null ? void 0 : _states$current$get.status) !== 'resolved') {
|
|
122
|
+
states.current.set(slot.id, {
|
|
123
|
+
status: 'late'
|
|
124
|
+
});
|
|
125
|
+
notify();
|
|
126
|
+
}
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (!pending.current.has(slot.id) && pending.current.size >= maxSlots) {
|
|
130
|
+
states.current.set(slot.id, {
|
|
131
|
+
status: 'late'
|
|
132
|
+
});
|
|
133
|
+
notify();
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
pending.current.set(slot.id, slot);
|
|
137
|
+
if (((_states$current$get2 = states.current.get(slot.id)) == null ? void 0 : _states$current$get2.status) !== 'resolved') {
|
|
138
|
+
states.current.set(slot.id, {
|
|
139
|
+
status: 'pending'
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
if (!scheduled.current) {
|
|
143
|
+
scheduled.current = true;
|
|
144
|
+
// One microtask after the commit that declared the slots: late enough
|
|
145
|
+
// that every section on the page has registered, early enough that the
|
|
146
|
+
// request is in flight before paint.
|
|
147
|
+
queueMicrotask(() => {
|
|
148
|
+
void flush();
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}, [resolveImageSet, maxSlots, flush, notify]);
|
|
152
|
+
const unregister = (0, _react.useCallback)(id => {
|
|
153
|
+
// Only meaningful before the flush; afterwards the set is immutable.
|
|
154
|
+
if (!flushed.current) {
|
|
155
|
+
pending.current.delete(id);
|
|
156
|
+
states.current.delete(id);
|
|
157
|
+
}
|
|
158
|
+
}, []);
|
|
159
|
+
const stateOf = (0, _react.useCallback)(id => states.current.get(id) ?? (resolveImageSet ? {
|
|
160
|
+
status: 'pending'
|
|
161
|
+
} : IDLE_STATE), [resolveImageSet]);
|
|
162
|
+
const subscribe = (0, _react.useCallback)(listener => {
|
|
163
|
+
listeners.current.add(listener);
|
|
164
|
+
return () => {
|
|
165
|
+
listeners.current.delete(listener);
|
|
166
|
+
};
|
|
167
|
+
}, []);
|
|
168
|
+
const value = (0, _react.useMemo)(() => ({
|
|
169
|
+
register,
|
|
170
|
+
unregister,
|
|
171
|
+
stateOf,
|
|
172
|
+
subscribe,
|
|
173
|
+
enabled: Boolean(resolveImageSet)
|
|
174
|
+
}), [register, unregister, stateOf, subscribe, resolveImageSet]);
|
|
175
|
+
return /*#__PURE__*/_react.default.createElement(ImageSetContext.Provider, {
|
|
176
|
+
value: value,
|
|
177
|
+
__self: void 0,
|
|
178
|
+
__source: {
|
|
179
|
+
fileName: _jsxFileName,
|
|
180
|
+
lineNumber: 240,
|
|
181
|
+
columnNumber: 5
|
|
182
|
+
}
|
|
183
|
+
}, children);
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Declare one image slot and read back what the page-wide resolution gave it.
|
|
188
|
+
*
|
|
189
|
+
* Returns `{ status: 'unavailable' }` when no provider or no resolver is
|
|
190
|
+
* present — storybook, tests, a host that has not adopted this yet — so a
|
|
191
|
+
* caller can render its existing image path unchanged in that case rather than
|
|
192
|
+
* guard on the provider's existence.
|
|
193
|
+
*
|
|
194
|
+
* `request` is read on every render but only its identity matters for
|
|
195
|
+
* re-registration, so callers should memoise it (or let its fields be stable).
|
|
196
|
+
*/
|
|
197
|
+
exports.ImageSetProvider = ImageSetProvider;
|
|
198
|
+
function useImageSlot(request) {
|
|
199
|
+
const ctx = (0, _react.useContext)(ImageSetContext);
|
|
200
|
+
const [, forceRender] = (0, _react.useState)(0);
|
|
201
|
+
const id = request == null ? void 0 : request.id;
|
|
202
|
+
|
|
203
|
+
// Subscribe BEFORE registering, and keep that order: registering can settle
|
|
204
|
+
// this slot synchronously — a slot arriving after the set was already sent is
|
|
205
|
+
// told `late` inside `register` itself — and a notification fired before this
|
|
206
|
+
// component was listening would be lost, leaving it stuck on `pending`
|
|
207
|
+
// forever. Effects run in declaration order, so this one wins.
|
|
208
|
+
(0, _react.useEffect)(() => {
|
|
209
|
+
if (!ctx) {
|
|
210
|
+
return undefined;
|
|
211
|
+
}
|
|
212
|
+
return ctx.subscribe(() => forceRender(n => n + 1));
|
|
213
|
+
}, [ctx]);
|
|
214
|
+
(0, _react.useEffect)(() => {
|
|
215
|
+
if (!ctx || !request) {
|
|
216
|
+
return undefined;
|
|
217
|
+
}
|
|
218
|
+
ctx.register(request);
|
|
219
|
+
return () => ctx.unregister(request.id);
|
|
220
|
+
// Registration is keyed on the slot's own content: a section that changes
|
|
221
|
+
// what it is asking for re-declares, one that merely re-renders does not.
|
|
222
|
+
}, [ctx, request == null ? void 0 : request.id, request == null ? void 0 : request.kind, request == null ? void 0 : request.ratio, request == null ? void 0 : request.semantic, request == null ? void 0 : request.entityId, request == null ? void 0 : request.renderWidthPx]);
|
|
223
|
+
if (!ctx || !id) {
|
|
224
|
+
return IDLE_STATE;
|
|
225
|
+
}
|
|
226
|
+
return ctx.stateOf(id);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/** True when a host has wired a resolver — i.e. slots will actually resolve. */
|
|
230
|
+
function useImageSetEnabled() {
|
|
231
|
+
var _useContext;
|
|
232
|
+
return ((_useContext = (0, _react.useContext)(ImageSetContext)) == null ? void 0 : _useContext.enabled) ?? false;
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=ImageSetContext.js.map
|