@page-speed/img 0.4.5 → 0.4.7
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/LICENSE +1 -1
- package/README.md +163 -36
- package/dist/browser/page-speed-img.umd.cjs +1 -1
- package/dist/browser/page-speed-img.umd.js +1 -1
- package/dist/browser/page-speed-img.umd.js.map +1 -1
- package/dist/core/Img.cjs +54 -53
- package/dist/core/Img.d.ts +4 -0
- package/dist/core/Img.js +54 -53
- package/dist/core/OptixFlowConfig.cjs +30 -0
- package/dist/core/OptixFlowConfig.d.ts +37 -0
- package/dist/core/OptixFlowConfig.js +30 -0
- package/dist/core/index.cjs +2 -1
- package/dist/core/index.d.ts +4 -1
- package/dist/core/index.js +2 -1
- package/dist/core/useImgDebugLog.cjs +46 -0
- package/dist/core/useImgDebugLog.d.ts +20 -0
- package/dist/core/useImgDebugLog.js +46 -0
- package/dist/index.cjs +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/package.json +5 -4
- package/dist/browser/opensite-img.umd.cjs +0 -2
- package/dist/browser/opensite-img.umd.js +0 -2
- package/dist/browser/opensite-img.umd.js.map +0 -1
- package/dist/types.cjs +0 -1
- package/dist/types.d.ts +0 -6
- package/dist/types.js +0 -1
- package/dist/utils/api.cjs +0 -94
- package/dist/utils/api.d.ts +0 -11
- package/dist/utils/api.js +0 -94
- package/dist/utils/cache.cjs +0 -12
- package/dist/utils/cache.d.ts +0 -3
- package/dist/utils/cache.js +0 -12
package/dist/core/Img.cjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { forwardRef, memo, useCallback,
|
|
3
|
+
import { forwardRef, memo, useCallback, useMemo, useRef } from "react";
|
|
4
4
|
import { useOptimizedImage } from "@page-speed/hooks/media";
|
|
5
|
+
import { useImgDebugLog } from "./useImgDebugLog.js";
|
|
5
6
|
import { useMediaSelectionEffect } from "./useMediaSelectionEffect.js";
|
|
6
7
|
import { useResponsiveReset } from "./useResponsiveReset.js";
|
|
7
8
|
const TRANSPARENT_PIXEL = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
|
|
@@ -20,7 +21,6 @@ const resolveOptixFlowConfig = (config) => {
|
|
|
20
21
|
export const setDefaultOptixFlowConfig = (config) => {
|
|
21
22
|
defaultOptixFlowConfig = config ?? undefined;
|
|
22
23
|
};
|
|
23
|
-
const isUrlString = (value) => typeof value === "string" && value.trim().length > 0;
|
|
24
24
|
const parseDimension = (value) => {
|
|
25
25
|
if (value === "" || value === null || typeof value === "undefined")
|
|
26
26
|
return undefined;
|
|
@@ -44,18 +44,19 @@ const composeRefs = (hookRef, forwardedRef, localRef) => useCallback((node) => {
|
|
|
44
44
|
forwardedRef.current = node;
|
|
45
45
|
}
|
|
46
46
|
}, [hookRef, forwardedRef, localRef]);
|
|
47
|
-
const ModernImg = ({ sizes, loading, decoding, alt, title, src: directSrc, eager, intersectionMargin, intersectionThreshold, optixFlowConfig, forwardedRef, ...
|
|
47
|
+
const ModernImg = ({ sizes, loading, decoding, alt, title, src: directSrc, eager, width, height, fetchPriority, intersectionMargin, intersectionThreshold, optixFlowConfig, useDebugMode, forwardedRef, ...restProps }) => {
|
|
48
48
|
const imgRef = useRef(null);
|
|
49
49
|
const pictureRef = useRef(null);
|
|
50
|
-
const logKeyRef = useRef(null);
|
|
51
50
|
useResponsiveReset(pictureRef);
|
|
52
51
|
useMediaSelectionEffect();
|
|
53
52
|
const normalizedSrc = useMemo(() => (typeof directSrc === "string" ? directSrc.trim() : ""), [directSrc]);
|
|
54
|
-
const numericWidth = useMemo(() => parseDimension(
|
|
55
|
-
const numericHeight = useMemo(() => parseDimension(
|
|
53
|
+
const numericWidth = useMemo(() => parseDimension(width), [width]);
|
|
54
|
+
const numericHeight = useMemo(() => parseDimension(height), [height]);
|
|
56
55
|
const resolvedOptixConfig = useMemo(() => resolveOptixFlowConfig(optixFlowConfig), [optixFlowConfig]);
|
|
57
|
-
const eagerLoad =
|
|
58
|
-
|
|
56
|
+
const eagerLoad = useMemo(() => {
|
|
57
|
+
return eager ?? loading === "eager";
|
|
58
|
+
}, [eager, loading]);
|
|
59
|
+
const hookOptions = useMemo(() => ({
|
|
59
60
|
src: normalizedSrc,
|
|
60
61
|
eager: eagerLoad,
|
|
61
62
|
width: numericWidth,
|
|
@@ -63,57 +64,57 @@ const ModernImg = ({ sizes, loading, decoding, alt, title, src: directSrc, eager
|
|
|
63
64
|
rootMargin: intersectionMargin ?? "200px",
|
|
64
65
|
threshold: intersectionThreshold ?? 0.1,
|
|
65
66
|
optixFlowConfig: resolvedOptixConfig,
|
|
66
|
-
})
|
|
67
|
+
}), [
|
|
68
|
+
normalizedSrc,
|
|
69
|
+
eagerLoad,
|
|
70
|
+
numericWidth,
|
|
71
|
+
numericHeight,
|
|
72
|
+
intersectionMargin,
|
|
73
|
+
intersectionThreshold,
|
|
74
|
+
resolvedOptixConfig,
|
|
75
|
+
]);
|
|
76
|
+
const { ref: hookRef, src, srcset, sizes: computedSizes, loading: hookLoading, isInView, size, } = useOptimizedImage(hookOptions);
|
|
67
77
|
const mergedRef = composeRefs(hookRef, forwardedRef, imgRef);
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if (typeof console !== "undefined" && console.info) {
|
|
98
|
-
console.info("[PageSpeedImg] image request", {
|
|
99
|
-
src: imgSrc,
|
|
100
|
-
srcset,
|
|
101
|
-
sizes: sizesAttr,
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
}, [
|
|
78
|
+
const sizesAttr = useMemo(() => {
|
|
79
|
+
return sizes ?? (computedSizes || undefined);
|
|
80
|
+
}, [sizes, computedSizes]);
|
|
81
|
+
const loadingAttr = useMemo(() => {
|
|
82
|
+
return loading ?? hookLoading ?? "lazy";
|
|
83
|
+
}, [loading, hookLoading]);
|
|
84
|
+
const decodingAttr = useMemo(() => {
|
|
85
|
+
return decoding ?? "async";
|
|
86
|
+
}, [decoding]);
|
|
87
|
+
const fetchPriorityAttr = useMemo(() => {
|
|
88
|
+
return fetchPriority ?? (eagerLoad ? "high" : undefined);
|
|
89
|
+
}, [fetchPriority, eagerLoad]);
|
|
90
|
+
const hasSrcSet = useMemo(() => {
|
|
91
|
+
return Boolean(srcset.avif || srcset.webp || srcset.jpeg);
|
|
92
|
+
}, [srcset.avif, srcset.webp, srcset.jpeg]);
|
|
93
|
+
const imgSrc = useMemo(() => {
|
|
94
|
+
return src || normalizedSrc || TRANSPARENT_PIXEL;
|
|
95
|
+
}, [src, normalizedSrc]);
|
|
96
|
+
const inlineSrcSet = useMemo(() => {
|
|
97
|
+
return hasSrcSet && !srcset.avif && !srcset.webp ? srcset.jpeg : "";
|
|
98
|
+
}, [hasSrcSet, srcset.avif, srcset.webp, srcset.jpeg]);
|
|
99
|
+
const widthAttr = useMemo(() => {
|
|
100
|
+
return numericWidth ?? (size.width || undefined);
|
|
101
|
+
}, [numericWidth, size?.width]);
|
|
102
|
+
const heightAttr = useMemo(() => {
|
|
103
|
+
return numericHeight ?? (size.height || undefined);
|
|
104
|
+
}, [numericHeight, size?.height]);
|
|
105
|
+
useImgDebugLog({
|
|
106
|
+
enabled: useDebugMode ?? false,
|
|
105
107
|
eagerLoad,
|
|
106
|
-
imgSrc,
|
|
107
108
|
isInView,
|
|
109
|
+
imgSrc,
|
|
110
|
+
transparentPixel: TRANSPARENT_PIXEL,
|
|
111
|
+
srcset,
|
|
108
112
|
sizesAttr,
|
|
109
|
-
|
|
110
|
-
srcset.webp,
|
|
111
|
-
srcset.jpeg,
|
|
112
|
-
]);
|
|
113
|
+
});
|
|
113
114
|
if (!hasSrcSet) {
|
|
114
|
-
return (_jsx("img", { ref: mergedRef, src: imgSrc, loading: loadingAttr, decoding: decodingAttr, alt: alt, title: title, width: widthAttr, height: heightAttr, ...restProps }));
|
|
115
|
+
return (_jsx("img", { ref: mergedRef, src: imgSrc, loading: loadingAttr, decoding: decodingAttr, fetchPriority: fetchPriorityAttr, alt: alt, title: title, width: widthAttr, height: heightAttr, ...restProps }));
|
|
115
116
|
}
|
|
116
|
-
return (_jsxs("picture", { ref: pictureRef, children: [srcset.avif ? (_jsx("source", { type: "image/avif", srcSet: srcset.avif, sizes: sizesAttr })) : null, srcset.webp ? (_jsx("source", { type: "image/webp", srcSet: srcset.webp, sizes: sizesAttr })) : null, _jsx("img", { ref: mergedRef, src: imgSrc, srcSet: inlineSrcSet || undefined, sizes: inlineSrcSet ? sizesAttr : undefined, loading: loadingAttr, decoding: decodingAttr, alt: alt, title: title, width: widthAttr, height: heightAttr, ...restProps })] }));
|
|
117
|
+
return (_jsxs("picture", { ref: pictureRef, children: [srcset.avif ? (_jsx("source", { type: "image/avif", srcSet: srcset.avif, sizes: sizesAttr })) : null, srcset.webp ? (_jsx("source", { type: "image/webp", srcSet: srcset.webp, sizes: sizesAttr })) : null, _jsx("img", { ref: mergedRef, src: imgSrc, srcSet: inlineSrcSet || undefined, sizes: inlineSrcSet ? sizesAttr : undefined, loading: loadingAttr, decoding: decodingAttr, fetchPriority: fetchPriorityAttr, alt: alt, title: title, width: widthAttr, height: heightAttr, ...restProps })] }));
|
|
117
118
|
};
|
|
118
119
|
const ImgBase = forwardRef(function Img(props, ref) {
|
|
119
120
|
const hasSrc = typeof props.src === "string" && props.src.trim().length > 0;
|
package/dist/core/Img.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export type ImgProps = NativeImgProps & {
|
|
|
14
14
|
intersectionMargin?: string;
|
|
15
15
|
/** OptixFlow integration options */
|
|
16
16
|
optixFlowConfig?: UseOptimizedImageOptions["optixFlowConfig"];
|
|
17
|
+
/** Enable debug logging for image requests */
|
|
18
|
+
useDebugMode?: boolean;
|
|
17
19
|
};
|
|
18
20
|
export declare const setDefaultOptixFlowConfig: (config?: UseOptimizedImageOptions["optixFlowConfig"] | null) => void;
|
|
19
21
|
export declare const Img: React.MemoExoticComponent<React.ForwardRefExoticComponent<Omit<React.ImgHTMLAttributes<HTMLImageElement>, "src" | "srcSet" | "sizes"> & {
|
|
@@ -29,5 +31,7 @@ export declare const Img: React.MemoExoticComponent<React.ForwardRefExoticCompon
|
|
|
29
31
|
intersectionMargin?: string;
|
|
30
32
|
/** OptixFlow integration options */
|
|
31
33
|
optixFlowConfig?: UseOptimizedImageOptions["optixFlowConfig"];
|
|
34
|
+
/** Enable debug logging for image requests */
|
|
35
|
+
useDebugMode?: boolean;
|
|
32
36
|
} & React.RefAttributes<HTMLImageElement>>>;
|
|
33
37
|
export {};
|
package/dist/core/Img.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { forwardRef, memo, useCallback,
|
|
3
|
+
import { forwardRef, memo, useCallback, useMemo, useRef } from "react";
|
|
4
4
|
import { useOptimizedImage } from "@page-speed/hooks/media";
|
|
5
|
+
import { useImgDebugLog } from "./useImgDebugLog.js";
|
|
5
6
|
import { useMediaSelectionEffect } from "./useMediaSelectionEffect.js";
|
|
6
7
|
import { useResponsiveReset } from "./useResponsiveReset.js";
|
|
7
8
|
const TRANSPARENT_PIXEL = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
|
|
@@ -20,7 +21,6 @@ const resolveOptixFlowConfig = (config) => {
|
|
|
20
21
|
export const setDefaultOptixFlowConfig = (config) => {
|
|
21
22
|
defaultOptixFlowConfig = config ?? undefined;
|
|
22
23
|
};
|
|
23
|
-
const isUrlString = (value) => typeof value === "string" && value.trim().length > 0;
|
|
24
24
|
const parseDimension = (value) => {
|
|
25
25
|
if (value === "" || value === null || typeof value === "undefined")
|
|
26
26
|
return undefined;
|
|
@@ -44,18 +44,19 @@ const composeRefs = (hookRef, forwardedRef, localRef) => useCallback((node) => {
|
|
|
44
44
|
forwardedRef.current = node;
|
|
45
45
|
}
|
|
46
46
|
}, [hookRef, forwardedRef, localRef]);
|
|
47
|
-
const ModernImg = ({ sizes, loading, decoding, alt, title, src: directSrc, eager, intersectionMargin, intersectionThreshold, optixFlowConfig, forwardedRef, ...
|
|
47
|
+
const ModernImg = ({ sizes, loading, decoding, alt, title, src: directSrc, eager, width, height, fetchPriority, intersectionMargin, intersectionThreshold, optixFlowConfig, useDebugMode, forwardedRef, ...restProps }) => {
|
|
48
48
|
const imgRef = useRef(null);
|
|
49
49
|
const pictureRef = useRef(null);
|
|
50
|
-
const logKeyRef = useRef(null);
|
|
51
50
|
useResponsiveReset(pictureRef);
|
|
52
51
|
useMediaSelectionEffect();
|
|
53
52
|
const normalizedSrc = useMemo(() => (typeof directSrc === "string" ? directSrc.trim() : ""), [directSrc]);
|
|
54
|
-
const numericWidth = useMemo(() => parseDimension(
|
|
55
|
-
const numericHeight = useMemo(() => parseDimension(
|
|
53
|
+
const numericWidth = useMemo(() => parseDimension(width), [width]);
|
|
54
|
+
const numericHeight = useMemo(() => parseDimension(height), [height]);
|
|
56
55
|
const resolvedOptixConfig = useMemo(() => resolveOptixFlowConfig(optixFlowConfig), [optixFlowConfig]);
|
|
57
|
-
const eagerLoad =
|
|
58
|
-
|
|
56
|
+
const eagerLoad = useMemo(() => {
|
|
57
|
+
return eager ?? loading === "eager";
|
|
58
|
+
}, [eager, loading]);
|
|
59
|
+
const hookOptions = useMemo(() => ({
|
|
59
60
|
src: normalizedSrc,
|
|
60
61
|
eager: eagerLoad,
|
|
61
62
|
width: numericWidth,
|
|
@@ -63,57 +64,57 @@ const ModernImg = ({ sizes, loading, decoding, alt, title, src: directSrc, eager
|
|
|
63
64
|
rootMargin: intersectionMargin ?? "200px",
|
|
64
65
|
threshold: intersectionThreshold ?? 0.1,
|
|
65
66
|
optixFlowConfig: resolvedOptixConfig,
|
|
66
|
-
})
|
|
67
|
+
}), [
|
|
68
|
+
normalizedSrc,
|
|
69
|
+
eagerLoad,
|
|
70
|
+
numericWidth,
|
|
71
|
+
numericHeight,
|
|
72
|
+
intersectionMargin,
|
|
73
|
+
intersectionThreshold,
|
|
74
|
+
resolvedOptixConfig,
|
|
75
|
+
]);
|
|
76
|
+
const { ref: hookRef, src, srcset, sizes: computedSizes, loading: hookLoading, isInView, size, } = useOptimizedImage(hookOptions);
|
|
67
77
|
const mergedRef = composeRefs(hookRef, forwardedRef, imgRef);
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if (typeof console !== "undefined" && console.info) {
|
|
98
|
-
console.info("[PageSpeedImg] image request", {
|
|
99
|
-
src: imgSrc,
|
|
100
|
-
srcset,
|
|
101
|
-
sizes: sizesAttr,
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
}, [
|
|
78
|
+
const sizesAttr = useMemo(() => {
|
|
79
|
+
return sizes ?? (computedSizes || undefined);
|
|
80
|
+
}, [sizes, computedSizes]);
|
|
81
|
+
const loadingAttr = useMemo(() => {
|
|
82
|
+
return loading ?? hookLoading ?? "lazy";
|
|
83
|
+
}, [loading, hookLoading]);
|
|
84
|
+
const decodingAttr = useMemo(() => {
|
|
85
|
+
return decoding ?? "async";
|
|
86
|
+
}, [decoding]);
|
|
87
|
+
const fetchPriorityAttr = useMemo(() => {
|
|
88
|
+
return fetchPriority ?? (eagerLoad ? "high" : undefined);
|
|
89
|
+
}, [fetchPriority, eagerLoad]);
|
|
90
|
+
const hasSrcSet = useMemo(() => {
|
|
91
|
+
return Boolean(srcset.avif || srcset.webp || srcset.jpeg);
|
|
92
|
+
}, [srcset.avif, srcset.webp, srcset.jpeg]);
|
|
93
|
+
const imgSrc = useMemo(() => {
|
|
94
|
+
return src || normalizedSrc || TRANSPARENT_PIXEL;
|
|
95
|
+
}, [src, normalizedSrc]);
|
|
96
|
+
const inlineSrcSet = useMemo(() => {
|
|
97
|
+
return hasSrcSet && !srcset.avif && !srcset.webp ? srcset.jpeg : "";
|
|
98
|
+
}, [hasSrcSet, srcset.avif, srcset.webp, srcset.jpeg]);
|
|
99
|
+
const widthAttr = useMemo(() => {
|
|
100
|
+
return numericWidth ?? (size.width || undefined);
|
|
101
|
+
}, [numericWidth, size?.width]);
|
|
102
|
+
const heightAttr = useMemo(() => {
|
|
103
|
+
return numericHeight ?? (size.height || undefined);
|
|
104
|
+
}, [numericHeight, size?.height]);
|
|
105
|
+
useImgDebugLog({
|
|
106
|
+
enabled: useDebugMode ?? false,
|
|
105
107
|
eagerLoad,
|
|
106
|
-
imgSrc,
|
|
107
108
|
isInView,
|
|
109
|
+
imgSrc,
|
|
110
|
+
transparentPixel: TRANSPARENT_PIXEL,
|
|
111
|
+
srcset,
|
|
108
112
|
sizesAttr,
|
|
109
|
-
|
|
110
|
-
srcset.webp,
|
|
111
|
-
srcset.jpeg,
|
|
112
|
-
]);
|
|
113
|
+
});
|
|
113
114
|
if (!hasSrcSet) {
|
|
114
|
-
return (_jsx("img", { ref: mergedRef, src: imgSrc, loading: loadingAttr, decoding: decodingAttr, alt: alt, title: title, width: widthAttr, height: heightAttr, ...restProps }));
|
|
115
|
+
return (_jsx("img", { ref: mergedRef, src: imgSrc, loading: loadingAttr, decoding: decodingAttr, fetchPriority: fetchPriorityAttr, alt: alt, title: title, width: widthAttr, height: heightAttr, ...restProps }));
|
|
115
116
|
}
|
|
116
|
-
return (_jsxs("picture", { ref: pictureRef, children: [srcset.avif ? (_jsx("source", { type: "image/avif", srcSet: srcset.avif, sizes: sizesAttr })) : null, srcset.webp ? (_jsx("source", { type: "image/webp", srcSet: srcset.webp, sizes: sizesAttr })) : null, _jsx("img", { ref: mergedRef, src: imgSrc, srcSet: inlineSrcSet || undefined, sizes: inlineSrcSet ? sizesAttr : undefined, loading: loadingAttr, decoding: decodingAttr, alt: alt, title: title, width: widthAttr, height: heightAttr, ...restProps })] }));
|
|
117
|
+
return (_jsxs("picture", { ref: pictureRef, children: [srcset.avif ? (_jsx("source", { type: "image/avif", srcSet: srcset.avif, sizes: sizesAttr })) : null, srcset.webp ? (_jsx("source", { type: "image/webp", srcSet: srcset.webp, sizes: sizesAttr })) : null, _jsx("img", { ref: mergedRef, src: imgSrc, srcSet: inlineSrcSet || undefined, sizes: inlineSrcSet ? sizesAttr : undefined, loading: loadingAttr, decoding: decodingAttr, fetchPriority: fetchPriorityAttr, alt: alt, title: title, width: widthAttr, height: heightAttr, ...restProps })] }));
|
|
117
118
|
};
|
|
118
119
|
const ImgBase = forwardRef(function Img(props, ref) {
|
|
119
120
|
const hasSrc = typeof props.src === "string" && props.src.trim().length > 0;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { setDefaultOptixFlowConfig } from "./Img.js";
|
|
5
|
+
/**
|
|
6
|
+
* A component that sets the default OptixFlow configuration for all Img components
|
|
7
|
+
* in an SSR-safe way. This component should be rendered once at the app root level.
|
|
8
|
+
*
|
|
9
|
+
* The config is applied inside a useEffect, which means it only runs on the client
|
|
10
|
+
* and is never executed during server-side rendering.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* // In your app root
|
|
15
|
+
* <OptixFlowConfig config={{ apiKey: 'your-api-key' }}>
|
|
16
|
+
* <App />
|
|
17
|
+
* </OptixFlowConfig>
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* Or without children:
|
|
21
|
+
* ```tsx
|
|
22
|
+
* <OptixFlowConfig config={{ apiKey: 'your-api-key' }} />
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function OptixFlowConfig({ config, children, }) {
|
|
26
|
+
React.useEffect(() => {
|
|
27
|
+
setDefaultOptixFlowConfig(config ?? null);
|
|
28
|
+
}, [config]);
|
|
29
|
+
return children ? _jsx(_Fragment, { children: children }) : null;
|
|
30
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { UseOptimizedImageOptions } from "@page-speed/hooks/media";
|
|
3
|
+
/**
|
|
4
|
+
* Props for the OptixFlowConfig component
|
|
5
|
+
*/
|
|
6
|
+
export interface OptixFlowConfigProps {
|
|
7
|
+
/**
|
|
8
|
+
* OptixFlow configuration to set as default for all images
|
|
9
|
+
* @example { apiKey: 'your-api-key', compressionLevel: 80 }
|
|
10
|
+
*/
|
|
11
|
+
config: UseOptimizedImageOptions["optixFlowConfig"];
|
|
12
|
+
/**
|
|
13
|
+
* Optional children (component returns null regardless)
|
|
14
|
+
*/
|
|
15
|
+
children?: React.ReactNode;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* A component that sets the default OptixFlow configuration for all Img components
|
|
19
|
+
* in an SSR-safe way. This component should be rendered once at the app root level.
|
|
20
|
+
*
|
|
21
|
+
* The config is applied inside a useEffect, which means it only runs on the client
|
|
22
|
+
* and is never executed during server-side rendering.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```tsx
|
|
26
|
+
* // In your app root
|
|
27
|
+
* <OptixFlowConfig config={{ apiKey: 'your-api-key' }}>
|
|
28
|
+
* <App />
|
|
29
|
+
* </OptixFlowConfig>
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* Or without children:
|
|
33
|
+
* ```tsx
|
|
34
|
+
* <OptixFlowConfig config={{ apiKey: 'your-api-key' }} />
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function OptixFlowConfig({ config, children, }: OptixFlowConfigProps): React.ReactElement | null;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { setDefaultOptixFlowConfig } from "./Img.js";
|
|
5
|
+
/**
|
|
6
|
+
* A component that sets the default OptixFlow configuration for all Img components
|
|
7
|
+
* in an SSR-safe way. This component should be rendered once at the app root level.
|
|
8
|
+
*
|
|
9
|
+
* The config is applied inside a useEffect, which means it only runs on the client
|
|
10
|
+
* and is never executed during server-side rendering.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* // In your app root
|
|
15
|
+
* <OptixFlowConfig config={{ apiKey: 'your-api-key' }}>
|
|
16
|
+
* <App />
|
|
17
|
+
* </OptixFlowConfig>
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* Or without children:
|
|
21
|
+
* ```tsx
|
|
22
|
+
* <OptixFlowConfig config={{ apiKey: 'your-api-key' }} />
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function OptixFlowConfig({ config, children, }) {
|
|
26
|
+
React.useEffect(() => {
|
|
27
|
+
setDefaultOptixFlowConfig(config ?? null);
|
|
28
|
+
}, [config]);
|
|
29
|
+
return children ? _jsx(_Fragment, { children: children }) : null;
|
|
30
|
+
}
|
package/dist/core/index.cjs
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { Img, setDefaultOptixFlowConfig } from
|
|
1
|
+
export { Img, setDefaultOptixFlowConfig } from "./Img.js";
|
|
2
|
+
export { OptixFlowConfig } from "./OptixFlowConfig.js";
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1 +1,4 @@
|
|
|
1
|
-
export { Img, setDefaultOptixFlowConfig } from
|
|
1
|
+
export { Img, setDefaultOptixFlowConfig } from "./Img.js";
|
|
2
|
+
export type { ImgProps } from "./Img.js";
|
|
3
|
+
export { OptixFlowConfig } from "./OptixFlowConfig.js";
|
|
4
|
+
export type { OptixFlowConfigProps } from "./OptixFlowConfig.js";
|
package/dist/core/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { Img, setDefaultOptixFlowConfig } from
|
|
1
|
+
export { Img, setDefaultOptixFlowConfig } from "./Img.js";
|
|
2
|
+
export { OptixFlowConfig } from "./OptixFlowConfig.js";
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Logs image-request details to the console when `enabled` is true.
|
|
4
|
+
* When disabled (the default), the hook short-circuits on the very first
|
|
5
|
+
* line so there is no meaningful runtime cost.
|
|
6
|
+
*/
|
|
7
|
+
export function useImgDebugLog({ enabled, eagerLoad, isInView, imgSrc, transparentPixel, srcset, sizesAttr, }) {
|
|
8
|
+
const logKeyRef = useRef(null);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
if (!enabled)
|
|
11
|
+
return;
|
|
12
|
+
if (typeof window === "undefined")
|
|
13
|
+
return;
|
|
14
|
+
if (!eagerLoad && !isInView)
|
|
15
|
+
return;
|
|
16
|
+
if (!imgSrc || imgSrc === transparentPixel)
|
|
17
|
+
return;
|
|
18
|
+
const logKey = [
|
|
19
|
+
imgSrc,
|
|
20
|
+
srcset.avif,
|
|
21
|
+
srcset.webp,
|
|
22
|
+
srcset.jpeg,
|
|
23
|
+
sizesAttr ?? "",
|
|
24
|
+
].join("|");
|
|
25
|
+
if (logKeyRef.current === logKey)
|
|
26
|
+
return;
|
|
27
|
+
logKeyRef.current = logKey;
|
|
28
|
+
if (typeof console !== "undefined" && console.info) {
|
|
29
|
+
console.info("[PageSpeedImg] image request", {
|
|
30
|
+
src: imgSrc,
|
|
31
|
+
srcset,
|
|
32
|
+
sizes: sizesAttr,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}, [
|
|
36
|
+
enabled,
|
|
37
|
+
eagerLoad,
|
|
38
|
+
imgSrc,
|
|
39
|
+
isInView,
|
|
40
|
+
sizesAttr,
|
|
41
|
+
srcset.avif,
|
|
42
|
+
srcset.webp,
|
|
43
|
+
srcset.jpeg,
|
|
44
|
+
transparentPixel,
|
|
45
|
+
]);
|
|
46
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
interface ImgDebugLogParams {
|
|
2
|
+
enabled: boolean;
|
|
3
|
+
eagerLoad: boolean;
|
|
4
|
+
isInView: boolean;
|
|
5
|
+
imgSrc: string;
|
|
6
|
+
transparentPixel: string;
|
|
7
|
+
srcset: {
|
|
8
|
+
avif: string;
|
|
9
|
+
webp: string;
|
|
10
|
+
jpeg: string;
|
|
11
|
+
};
|
|
12
|
+
sizesAttr: string | undefined;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Logs image-request details to the console when `enabled` is true.
|
|
16
|
+
* When disabled (the default), the hook short-circuits on the very first
|
|
17
|
+
* line so there is no meaningful runtime cost.
|
|
18
|
+
*/
|
|
19
|
+
export declare function useImgDebugLog({ enabled, eagerLoad, isInView, imgSrc, transparentPixel, srcset, sizesAttr, }: ImgDebugLogParams): void;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Logs image-request details to the console when `enabled` is true.
|
|
4
|
+
* When disabled (the default), the hook short-circuits on the very first
|
|
5
|
+
* line so there is no meaningful runtime cost.
|
|
6
|
+
*/
|
|
7
|
+
export function useImgDebugLog({ enabled, eagerLoad, isInView, imgSrc, transparentPixel, srcset, sizesAttr, }) {
|
|
8
|
+
const logKeyRef = useRef(null);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
if (!enabled)
|
|
11
|
+
return;
|
|
12
|
+
if (typeof window === "undefined")
|
|
13
|
+
return;
|
|
14
|
+
if (!eagerLoad && !isInView)
|
|
15
|
+
return;
|
|
16
|
+
if (!imgSrc || imgSrc === transparentPixel)
|
|
17
|
+
return;
|
|
18
|
+
const logKey = [
|
|
19
|
+
imgSrc,
|
|
20
|
+
srcset.avif,
|
|
21
|
+
srcset.webp,
|
|
22
|
+
srcset.jpeg,
|
|
23
|
+
sizesAttr ?? "",
|
|
24
|
+
].join("|");
|
|
25
|
+
if (logKeyRef.current === logKey)
|
|
26
|
+
return;
|
|
27
|
+
logKeyRef.current = logKey;
|
|
28
|
+
if (typeof console !== "undefined" && console.info) {
|
|
29
|
+
console.info("[PageSpeedImg] image request", {
|
|
30
|
+
src: imgSrc,
|
|
31
|
+
srcset,
|
|
32
|
+
sizes: sizesAttr,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}, [
|
|
36
|
+
enabled,
|
|
37
|
+
eagerLoad,
|
|
38
|
+
imgSrc,
|
|
39
|
+
isInView,
|
|
40
|
+
sizesAttr,
|
|
41
|
+
srcset.avif,
|
|
42
|
+
srcset.webp,
|
|
43
|
+
srcset.jpeg,
|
|
44
|
+
transparentPixel,
|
|
45
|
+
]);
|
|
46
|
+
}
|
package/dist/index.cjs
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -2,3 +2,5 @@ import type { UseOptimizedImageOptions } from '@page-speed/hooks/media';
|
|
|
2
2
|
export * from './core/index.js';
|
|
3
3
|
export type { ImageFormat, SrcsetByFormat, UseOptimizedImageOptions, UseOptimizedImageState, } from '@page-speed/hooks/media';
|
|
4
4
|
export type OptixFlowConfig = UseOptimizedImageOptions['optixFlowConfig'];
|
|
5
|
+
export { Img, setDefaultOptixFlowConfig, OptixFlowConfig } from './core/index.js';
|
|
6
|
+
export type { ImgProps, OptixFlowConfigProps } from './core/index.js';
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@page-speed/img",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.7",
|
|
4
4
|
"description": "Performance-optimized React Image component. Drop-in image implementation of web.dev best practices with zero configuration.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"url": "https://github.com/opensite-ai/page-speed-img/issues"
|
|
26
26
|
},
|
|
27
27
|
"author": "OpenSite AI (https://opensite.ai)",
|
|
28
|
-
"license": "BSD
|
|
28
|
+
"license": "BSD-3-Clause",
|
|
29
29
|
"private": false,
|
|
30
30
|
"type": "module",
|
|
31
31
|
"main": "dist/index.cjs",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"bundle-analysis": "node scripts/analyze-bundle.js || true",
|
|
67
67
|
"prepare": "husky",
|
|
68
68
|
"prepack": "pnpm run build",
|
|
69
|
-
"prepublishOnly": "pnpm run build"
|
|
69
|
+
"prepublishOnly": "pnpm run build && pnpm run test"
|
|
70
70
|
},
|
|
71
71
|
"peerDependencies": {
|
|
72
72
|
"react": ">=17.0.0",
|
|
@@ -75,6 +75,7 @@
|
|
|
75
75
|
"devDependencies": {
|
|
76
76
|
"@commitlint/cli": "^20.1.0",
|
|
77
77
|
"@commitlint/config-conventional": "^20.0.0",
|
|
78
|
+
"@testing-library/react": "^16.3.2",
|
|
78
79
|
"@types/node": "^20.17.6",
|
|
79
80
|
"@types/react": "^18.3.3",
|
|
80
81
|
"@types/react-dom": "^18.3.0",
|
|
@@ -90,7 +91,7 @@
|
|
|
90
91
|
"vitest": "^3.2.4"
|
|
91
92
|
},
|
|
92
93
|
"dependencies": {
|
|
93
|
-
"@opensite/hooks": "2.0
|
|
94
|
+
"@opensite/hooks": "2.1.0",
|
|
94
95
|
"@page-speed/hooks": "0.4.5"
|
|
95
96
|
},
|
|
96
97
|
"packageManager": "pnpm@10.24.0",
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).OpensiteImg={},t.React)}(this,function(t,e){"use strict";const n=new Map;function i(t,e){n.set(t,e)}const r="https://cdn.ing";function l(t){return(t??r).replace(/\/$/,"")}function o(t,e){return`${l(e)}/assets/images/${t}`}function s(t,e){return`${l(e)}/i/r/${t}`}function a(t){return!!t&&["AVIF","WEBP","JPEG"].some(e=>{const n=null==t?void 0:t[e];return!!(i=n)&&[i.sm,i.md,i.lg,i.full].some(t=>"string"==typeof t&&t.trim().length>0);var i})}function u(t){return"string"==typeof t&&t.trim().length>0}function d(t){var e;if(!t)return!1;if(a((null==(e=t.variants_data)?void 0:e.variants)??null))return!0;const n=t;return[n.img_url,n.file_data_url,n.file_data_thumbnail_url,n.img_src,n.med_src,n.thumb_src,n.low_res_thumb].some(u)}async function c(t,e){const n=await fetch(t,{signal:e});if(!n.ok){const e=new Error(`Failed to fetch image data (status ${n.status}) from ${t}`);throw e.status=n.status,e}return await n.json()}async function f(t,e={}){if(!Number.isFinite(t))throw new Error("Invalid mediaId provided to fetchImageData");const r=l(e.cdnHost),a=`image:${r}:${t}`;if(!e.bypassCache){const t=(u=a,n.get(u));if(t)return t}var u;const f=[o(t,r),s(t,r)];let m;for(const n of f)try{const t=await c(n,e.signal);return d(t)&&i(a,t),t}catch(v){if("AbortError"===(null==v?void 0:v.name))throw v;m=v}if(m instanceof Error)throw m;throw new Error(`Failed to fetch image data for mediaId ${t}`)}const m="dt:media-selected";function v(t){t&&t.querySelectorAll("source").forEach(t=>{const e=t.getAttribute("srcset");e&&(t.setAttribute("data-srcset",e),t.removeAttribute("srcset"),requestAnimationFrame(()=>{t.setAttribute("srcset",e)}))})}const g={sm:640,md:1024,lg:1536,full:2560},h=t=>"string"==typeof t&&t.trim().length>0;function p(t){const e=null==t?void 0:t.widths;return e?{sm:e.small??e.sm??g.sm,md:e.medium??e.md??g.md,lg:e.large??e.lg??g.lg,full:e.full_size??e.full??g.full}:null}function w(t){if(t)return t.md||t.lg||t.sm||t.full||Object.values(t).find(Boolean)}const _=e.forwardRef(function({mediaId:t,cdnHost:n,sizes:i,onImageData:o,loading:s,decoding:u,alt:d,title:c,src:_,...E},b){const y=e.useRef(null);e.useImperativeHandle(b,()=>y.current);!function(t){e.useEffect(()=>{const e=t.current;e&&(e instanceof HTMLPictureElement?v(e):e.parentElement instanceof HTMLPictureElement&&v(e.parentElement))},[t])}(e.useRef(null)),e.useEffect(()=>{if("undefined"==typeof window)return;const t=()=>{};return window.addEventListener(m,t),()=>window.removeEventListener(m,t)},[]);const[$,I]=e.useState(null),[S,M]=e.useState(0),x=Number.isFinite(t),z=s??"lazy",A=u??"async",[O,N]=e.useState(()=>!x||"lazy"!==z),P=e.useMemo(()=>(n??r).replace(/\/$/,""),[n]);e.useEffect(()=>{if(!x)return I(null),void M(0);I(null),M(0)},[x,t,n]),e.useEffect(()=>{if(!x)return;const e=new AbortController;return f(t,{cdnHost:n,signal:e.signal,bypassCache:S>0}).then(t=>{I(t),null==o||o(t)}).catch(t=>{"AbortError"!==(null==t?void 0:t.name)&&console.warn("Image data fetch failed:",t)}),()=>e.abort()},[x,t,n,o,S]),e.useEffect(()=>{N(!x||"lazy"!==z)},[x,t,z]),e.useEffect(()=>{if(!x||"lazy"!==z||O)return;if("undefined"==typeof window||void 0===window.IntersectionObserver)return void N(!0);const t=y.current;if(!t)return;const e=new IntersectionObserver(t=>{t.some(t=>t.isIntersecting)&&(N(!0),e.disconnect())},{rootMargin:"200px"});return e.observe(t),()=>e.disconnect()},[x,z,O]);const T=e.useMemo(()=>{var t,e,n;if(!$)return null;const i=(null==(t=$.variants_data)?void 0:t.variants)??{},r=i.WEBP,l=i.AVIF,o=i.JPEG,s=p(null==(e=i.WEBP)?void 0:e.metadata)||p(null==(n=i.JPEG)?void 0:n.metadata)||{...g},a=t=>(t=>{if(h(t))return/^https?:\/\//i.test(t)||t.startsWith("data:")?t:t.startsWith("//")?`https:${t}`:t.startsWith("/")?`${P}${t}`:`${P}/${t}`})("string"==typeof t?t:void 0),u=[w(r),w(o),w(l),null==r?void 0:r.sm,null==r?void 0:r.md,null==r?void 0:r.lg,null==r?void 0:r.full,null==o?void 0:o.sm,null==o?void 0:o.md,null==o?void 0:o.lg,null==o?void 0:o.full,null==l?void 0:l.sm,null==l?void 0:l.md,null==l?void 0:l.lg,null==l?void 0:l.full].map(t=>a(t??void 0)).filter(h),d=$,c=[d.img_url,d.file_data_url,d.file_data_thumbnail_url,d.img_src,d.med_src,d.thumb_src,d.low_res_thumb].map(t=>h(t)?a(t):void 0).filter(h),f=d.fallback_url?[a(d.fallback_url)].filter(h):[],m=[...u,...c,...f][0];if(!m)return null;return{webp:r,avif:l,jpeg:o,toSrcSet:t=>{if(!t)return;const e=[],n=(t,n)=>{const i=a(t);i&&n&&e.push(`${i} ${n}w`)};return n(t.sm,s.sm),n(t.md,s.md),n(t.lg,s.lg),n(t.full,s.full),e.length?e.join(", "):void 0},fallback:m,widths:s,hasVariantSource:u.length>0}},[$,P]),j=e.useMemo(()=>{var t;return a((null==(t=null==$?void 0:$.variants_data)?void 0:t.variants)??null)},[$]),F=e.useMemo(()=>{var t;const e=(null==(t=null==$?void 0:$.variants_data)?void 0:t.status)??(null==$?void 0:$.variants_status)??"";return"string"==typeof e?e.toLowerCase():""},[$]),k="failed"===F||"error"===F,H=x&&Boolean($)&&!k&&!j&&S<5;e.useEffect(()=>{if(!H)return;if("undefined"==typeof window)return;const t=window.setTimeout(()=>{M(t=>t+1)},3e3);return()=>window.clearTimeout(t)},[H]);const L=e.useMemo(()=>{var t,e;return"string"==typeof d?d:(null==(e=null==(t=null==$?void 0:$.meta)?void 0:t.content_manifest)?void 0:e.summary)??void 0},[d,$]),V=e.useMemo(()=>{var t,e;return"string"==typeof c?c:(null==(e=null==(t=null==$?void 0:$.meta)?void 0:t.content_manifest)?void 0:e.title)??void 0},[c,$]),W=e.useMemo(()=>{var t,e,n,i;return(null==(e=null==(t=null==$?void 0:$.meta)?void 0:t.sizing)?void 0:e.width)??(null==(i=null==(n=null==$?void 0:$.variants_data)?void 0:n.metadata)?void 0:i.width)??void 0},[$]),B=e.useMemo(()=>{var t,e,n,i;return(null==(e=null==(t=null==$?void 0:$.meta)?void 0:t.sizing)?void 0:e.height)??(null==(i=null==(n=null==$?void 0:$.variants_data)?void 0:n.metadata)?void 0:i.height)??void 0},[$]),C=e.useMemo(()=>{var t,e;const n=null==(e=null==(t=null==$?void 0:$.meta)?void 0:t.content_manifest)?void 0:e.optimized_filename;if(!n)return;const i=null==T?void 0:T.fallback;if(!i)return;const r=i.lastIndexOf(".");return`${n}.${r>-1?i.slice(r+1).toLowerCase():"jpg"}`},[$,T]);if(!x){const t={...E};return e.createElement("img",{ref:y,src:_,loading:z,decoding:A,alt:L,title:V,width:t.width,height:t.height,...t})}const D=function(t,e){return`${l(e)}/assets/low_res_thumb/${t}`}(t,n);if(!$||!T||!O){const t={...E};return e.createElement("img",{ref:y,src:D,loading:z,decoding:A,alt:L,title:V,width:t.width??W,height:t.height??B,...t})}const R=i??"(max-width:640px) 640px, (max-width:1024px) 1024px, 1536px",{webp:q,avif:G,jpeg:J,toSrcSet:K,fallback:Q}=T,U=K(q),X=K(G),Y=K(J);return U||X||Y?e.createElement("picture",null,X?e.createElement("source",{type:"image/avif",srcSet:X,sizes:R}):null,U?e.createElement("source",{type:"image/webp",srcSet:U,sizes:R}):null,e.createElement("img",{ref:y,src:Q,srcSet:!Y||U||X?void 0:Y,sizes:!Y||U||X?void 0:R,loading:z,decoding:A,alt:L,title:V,width:W,height:B,"data-filename":C,...E})):e.createElement("img",{ref:y,src:Q,loading:z,decoding:A,alt:L,title:V,width:W,height:B,"data-filename":C,...E})}),E=e.memo(_);E.displayName="OpenSiteImg";const b="undefined"!=typeof globalThis?globalThis:void 0;if(b)if(b.process){const t=b.process.env??(b.process.env={});void 0===t.NODE_ENV&&(t.NODE_ENV="production")}else b.process={env:{NODE_ENV:"production"}};t.Img=E,Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})});
|
|
2
|
-
//# sourceMappingURL=opensite-img.umd.js.map
|