From 78d98a551966e9e50a0e094c93d5c3ae1b263755 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Thu, 12 Dec 2024 13:56:46 +0700 Subject: [PATCH] refactor: pass wsImageLoader directly (#4567) Split our saas image loader into separate function which is passed directly everywhere without createImageLoader. --- apps/builder/app/builder/builder.tsx | 3 - .../app/builder/features/marketplace/card.tsx | 7 +- .../builder/features/pages/search-preview.tsx | 8 +-- .../builder/features/pages/social-preview.tsx | 8 +-- .../project-settings/section-general.tsx | 14 ++-- .../project-settings/section-marketplace.tsx | 18 ++--- .../backgrounds/background-thumbnail.tsx | 9 ++- .../app/builder/shared/assets/use-assets.tsx | 10 +-- .../builder/shared/image-manager/image.tsx | 9 +-- apps/builder/app/canvas/canvas.tsx | 14 +--- .../app/dashboard/projects/thumbnail.tsx | 10 ++- apps/builder/app/routes/cgi.image.$.ts | 8 +-- apps/builder/app/shared/nano-states/misc.ts | 3 - packages/cli/src/prebuild.ts | 5 +- packages/image/src/image-dev.stories.tsx | 10 +-- packages/image/src/image-loader.test.ts | 11 ++- packages/image/src/image-loaders.ts | 72 ++++++++++--------- packages/image/src/image-optimize.test.ts | 22 +++--- 18 files changed, 91 insertions(+), 150 deletions(-) diff --git a/apps/builder/app/builder/builder.tsx b/apps/builder/app/builder/builder.tsx index 395d2d4d9209..8cbfa07fbe8b 100644 --- a/apps/builder/app/builder/builder.tsx +++ b/apps/builder/app/builder/builder.tsx @@ -6,7 +6,6 @@ import type { Build } from "@webstudio-is/project-build"; import type { Project } from "@webstudio-is/project"; import { theme, Box, type CSS, Flex, Grid } from "@webstudio-is/design-system"; import type { AuthPermit } from "@webstudio-is/trpc-interface/index.server"; -import { createImageLoader } from "@webstudio-is/image"; import { registerContainers, createObjectPool } from "~/shared/sync"; import { ServerSyncStorage, @@ -31,7 +30,6 @@ import { subscribeResources, $authTokenPermissions, $publisherHost, - $imageLoader, $isDesignMode, $isContentMode, $userPlanFeatures, @@ -236,7 +234,6 @@ export const Builder = ({ // additional data stores $project.set(project); $publisherHost.set(publisherHost); - $imageLoader.set(createImageLoader({})); $authPermit.set(authPermit); $authToken.set(authToken); $userPlanFeatures.set(userPlanFeatures); diff --git a/apps/builder/app/builder/features/marketplace/card.tsx b/apps/builder/app/builder/features/marketplace/card.tsx index 65a9bccd1888..e2a78291bdec 100644 --- a/apps/builder/app/builder/features/marketplace/card.tsx +++ b/apps/builder/app/builder/features/marketplace/card.tsx @@ -1,5 +1,4 @@ import { forwardRef } from "react"; -import { useStore } from "@nanostores/react"; import { Flex, Text, @@ -8,9 +7,8 @@ import { css, rawTheme, } from "@webstudio-is/design-system"; -import { Image } from "@webstudio-is/image"; +import { Image, wsImageLoader } from "@webstudio-is/image"; import { SpinnerIcon } from "@webstudio-is/icons"; -import { $imageLoader } from "~/shared/nano-states"; const focusOutline = focusRingStyle(); @@ -60,7 +58,6 @@ type ThumbnailProps = { }; const Thumbnail = ({ image, state, alt }: ThumbnailProps) => { - const imageLoader = useStore($imageLoader); return ( {image === "" || image === undefined ? ( @@ -79,7 +76,7 @@ const Thumbnail = ({ image, state, alt }: ThumbnailProps) => { )} diff --git a/apps/builder/app/builder/features/pages/search-preview.tsx b/apps/builder/app/builder/features/pages/search-preview.tsx index 0cd338571869..bf9cab85aace 100644 --- a/apps/builder/app/builder/features/pages/search-preview.tsx +++ b/apps/builder/app/builder/features/pages/search-preview.tsx @@ -1,7 +1,5 @@ -import { useStore } from "@nanostores/react"; import { Box, Flex, Grid } from "@webstudio-is/design-system"; -import { Image } from "@webstudio-is/image"; -import { $imageLoader } from "~/shared/nano-states"; +import { Image, wsImageLoader } from "@webstudio-is/image"; import { formatUrl, truncateByWords, truncate } from "./social-utils"; /** @@ -67,8 +65,6 @@ const VerticalThreePointIcon = () => ( ); export const SearchPreview = (props: SearchPreviewProps) => { - const imageLoader = useStore($imageLoader); - return ( { diff --git a/apps/builder/app/builder/features/pages/social-preview.tsx b/apps/builder/app/builder/features/pages/social-preview.tsx index 08902b5f8ecb..3fe15a86b002 100644 --- a/apps/builder/app/builder/features/pages/social-preview.tsx +++ b/apps/builder/app/builder/features/pages/social-preview.tsx @@ -1,8 +1,6 @@ import { Box, Grid, Label, css, theme } from "@webstudio-is/design-system"; -import { Image } from "@webstudio-is/image"; +import { Image, wsImageLoader } from "@webstudio-is/image"; import { truncateByWords, truncate } from "./social-utils"; -import { useStore } from "@nanostores/react"; -import { $imageLoader } from "~/shared/nano-states"; type SocialPreviewProps = { ogImageUrl?: string; @@ -33,8 +31,6 @@ export const SocialPreview = ({ ogTitle, ogUrl, }: SocialPreviewProps) => { - const imageLoader = useStore($imageLoader); - return ( @@ -49,7 +45,7 @@ export const SocialPreview = ({ > { const assets = useStore($assets); const asset = assets.get(meta.faviconAssetId ?? ""); const favIconUrl = asset ? `${asset.name}` : undefined; - const imageLoader = useStore($imageLoader); const handleSave = ( name: keyof ProjectMeta @@ -176,7 +170,7 @@ export const SectionGeneral = () => { height={72} className={imgStyle()} src={favIconUrl} - loader={imageLoader} + loader={wsImageLoader} /> diff --git a/apps/builder/app/builder/features/project-settings/section-marketplace.tsx b/apps/builder/app/builder/features/project-settings/section-marketplace.tsx index 46a8f48bf9cd..35020cf797d5 100644 --- a/apps/builder/app/builder/features/project-settings/section-marketplace.tsx +++ b/apps/builder/app/builder/features/project-settings/section-marketplace.tsx @@ -16,22 +16,17 @@ import { Select, Box, } from "@webstudio-is/design-system"; -import { ImageControl } from "./image-control"; -import { - $assets, - $imageLoader, - $marketplaceProduct, - $project, -} from "~/shared/nano-states"; -import { Image } from "@webstudio-is/image"; -import { useIds } from "~/shared/form-utils"; +import { Image, wsImageLoader } from "@webstudio-is/image"; import { useState } from "react"; import { MarketplaceProduct, marketplaceCategories, } from "@webstudio-is/project-build"; -import { serverSyncStore } from "~/shared/sync"; +import { ImageControl } from "./image-control"; +import { $assets, $marketplaceProduct, $project } from "~/shared/nano-states"; +import { useIds } from "~/shared/form-utils"; import { MarketplaceApprovalStatus } from "@webstudio-is/project"; +import { serverSyncStore } from "~/shared/sync"; import { trpcClient } from "~/shared/trpc/trpc-client"; import { rightPanelWidth, sectionSpacing } from "./utils"; @@ -123,7 +118,6 @@ const useMarketplaceApprovalStatus = () => { export const SectionMarketplace = () => { const project = useStore($project); - const imageLoader = useStore($imageLoader); const approval = useMarketplaceApprovalStatus(); const [data, setData] = useState(() => $marketplaceProduct.get()); const ids = useIds([ @@ -221,7 +215,7 @@ export const SectionMarketplace = () => { hasAsset: asset !== undefined, })} src={asset ? `${asset.name}` : undefined} - loader={imageLoader} + loader={wsImageLoader} /> diff --git a/apps/builder/app/builder/features/style-panel/sections/backgrounds/background-thumbnail.tsx b/apps/builder/app/builder/features/style-panel/sections/backgrounds/background-thumbnail.tsx index 22f4e2d055bc..63db974353e4 100644 --- a/apps/builder/app/builder/features/style-panel/sections/backgrounds/background-thumbnail.tsx +++ b/apps/builder/app/builder/features/style-panel/sections/backgrounds/background-thumbnail.tsx @@ -1,13 +1,13 @@ import { useStore } from "@nanostores/react"; import type { Assets } from "@webstudio-is/sdk"; -import { Image as WebstudioImage } from "@webstudio-is/image"; +import { Image as WebstudioImage, wsImageLoader } from "@webstudio-is/image"; import { styled, theme } from "@webstudio-is/design-system"; import { StyleValue, toValue, type StyleProperty, } from "@webstudio-is/css-engine"; -import { $assets, $imageLoader } from "~/shared/nano-states"; +import { $assets } from "~/shared/nano-states"; import brokenImage from "~/shared/images/broken-image-placeholder.svg"; import { toPascalCase } from "../../shared/keyword-utils"; import { useComputedStyles } from "../../shared/model"; @@ -115,7 +115,6 @@ type RepeatedProperty = (typeof repeatedProperties)[number]; export const BackgroundThumbnail = ({ index }: { index: number }) => { const assets = useStore($assets); - const imageLoader = useStore($imageLoader); const styles = useComputedStyles(repeatedProperties); const [backgroundImage] = styles; const backgroundImageValue = getComputedRepeatedItem(backgroundImage, index); @@ -131,7 +130,7 @@ export const BackgroundThumbnail = ({ index }: { index: number }) => { return ( { return ( { @@ -251,8 +249,6 @@ const imageWidth = css({ }); const ToastImageInfo = ({ objectURL }: { objectURL: string }) => { - const imageLoader = useStore($imageLoader); - return ( { src={objectURL} optimize={false} width={64} - loader={imageLoader} + loader={wsImageLoader} /> ); diff --git a/apps/builder/app/builder/shared/image-manager/image.tsx b/apps/builder/app/builder/shared/image-manager/image.tsx index 59f51c86b437..e073bd694bc2 100644 --- a/apps/builder/app/builder/shared/image-manager/image.tsx +++ b/apps/builder/app/builder/shared/image-manager/image.tsx @@ -1,8 +1,4 @@ -import { useStore } from "@nanostores/react"; - -import { Image as WebstudioImage } from "@webstudio-is/image"; - -import { $imageLoader } from "~/shared/nano-states"; +import { Image as WebstudioImage, wsImageLoader } from "@webstudio-is/image"; type ImageProps = { assetId: string; @@ -22,7 +18,6 @@ export const Image = ({ width, }: ImageProps) => { const optimize = objectURL === undefined; - const imageLoader = useStore($imageLoader); // Avoid image flickering on switching from preview to asset (during upload) // Possible optimisation, we can set it to "sync" only if asset.path has changed or add isNew prop to UploadedAssetContainer @@ -43,7 +38,7 @@ export const Image = ({ maxWidth: "100%", }} key={assetId} - loader={imageLoader} + loader={wsImageLoader} decoding={decoding} src={src} width={width} diff --git a/apps/builder/app/canvas/canvas.tsx b/apps/builder/app/canvas/canvas.tsx index a8e1bf2cf577..68aeb640c9c5 100644 --- a/apps/builder/app/canvas/canvas.tsx +++ b/apps/builder/app/canvas/canvas.tsx @@ -8,6 +8,7 @@ import { coreMetas, corePropsMetas, } from "@webstudio-is/react-sdk"; +import { wsImageLoader } from "@webstudio-is/image"; import { ReactSdkContext } from "@webstudio-is/react-sdk/runtime"; import * as baseComponents from "@webstudio-is/sdk-components-react"; import * as baseComponentMetas from "@webstudio-is/sdk-components-react/metas"; @@ -61,7 +62,6 @@ import { subscribeInstanceHovering } from "./instance-hovering"; import { useHashLinkSync } from "~/shared/pages"; import { useMount } from "~/shared/hook-utils/use-mount"; import { subscribeInterceptedEvents } from "./interceptor"; -import { createImageLoader } from "@webstudio-is/image"; import { subscribeCommands } from "~/canvas/shared/commands"; import { updateCollaborativeInstanceRect } from "./collaborative-instance"; import { $params } from "./stores"; @@ -102,7 +102,6 @@ const useElementsTree = ( const page = useStore($selectedPage); const isPreviewMode = useStore($isPreviewMode); const rootInstanceId = page?.rootInstanceId ?? ""; - const imageLoader = useMemo(() => createImageLoader({}), []); if (typeof window === "undefined") { // @todo remove after https://github.com/webstudio-is/webstudio/issues/1313 now its needed to be sure that no leaks exists @@ -120,7 +119,7 @@ const useElementsTree = ( value={{ renderer: isPreviewMode ? "preview" : "canvas", assetBaseUrl: params.assetBaseUrl, - imageLoader, + imageLoader: wsImageLoader, resources: {}, }} > @@ -135,14 +134,7 @@ const useElementsTree = ( })} ); - }, [ - params, - instances, - rootInstanceId, - components, - isPreviewMode, - imageLoader, - ]); + }, [params, instances, rootInstanceId, components, isPreviewMode]); }; const DesignMode = () => { diff --git a/apps/builder/app/dashboard/projects/thumbnail.tsx b/apps/builder/app/dashboard/projects/thumbnail.tsx index a7a3801d9b9e..be58f029035e 100644 --- a/apps/builder/app/dashboard/projects/thumbnail.tsx +++ b/apps/builder/app/dashboard/projects/thumbnail.tsx @@ -1,5 +1,5 @@ -import { forwardRef, useMemo } from "react"; -import { createImageLoader, Image } from "@webstudio-is/image"; +import { forwardRef } from "react"; +import { Image, wsImageLoader } from "@webstudio-is/image"; import { css, theme, textVariants } from "@webstudio-is/design-system"; const abbrStyle = css(textVariants.brandThumbnailLargeDefault, { @@ -74,10 +74,9 @@ export const ThumbnailLinkWithImage = forwardRef< HTMLAnchorElement, { name: string; to: string } >(({ name, to }, ref) => { - const imageLoader = useMemo(() => createImageLoader({}), []); return ( - + ); }); @@ -90,7 +89,6 @@ export const ThumbnailWithImage = forwardRef< onClick: React.MouseEventHandler; } >(({ name, onClick }, ref) => { - const imageLoader = useMemo(() => createImageLoader({}), []); return (
- +
); }); diff --git a/apps/builder/app/routes/cgi.image.$.ts b/apps/builder/app/routes/cgi.image.$.ts index 6b89e2badb97..910827c07a5d 100644 --- a/apps/builder/app/routes/cgi.image.$.ts +++ b/apps/builder/app/routes/cgi.image.$.ts @@ -1,11 +1,11 @@ import { createReadStream, existsSync } from "node:fs"; import { join } from "node:path"; +import { z } from "zod"; import { createReadableStreamFromReadable } from "@remix-run/node"; import type { LoaderFunctionArgs } from "@remix-run/server-runtime"; +import { wsImageLoader } from "@webstudio-is/image"; import env from "~/env/env.server"; import { getImageNameAndType } from "~/builder/shared/assets/asset-utils"; -import { z } from "zod"; -import { createImageLoader } from "@webstudio-is/image"; const ImageParams = z.object({ width: z.string().transform((value) => Math.round(parseFloat(value))), @@ -72,9 +72,7 @@ export const loader = async ({ request }: LoaderFunctionArgs) => { } if (env.RESIZE_ORIGIN !== undefined) { - const imageLoader = createImageLoader({}); - - const imgHref = imageLoader({ + const imgHref = wsImageLoader({ src: name, ...imageParameters, format: "auto", diff --git a/apps/builder/app/shared/nano-states/misc.ts b/apps/builder/app/shared/nano-states/misc.ts index d76ce5927643..a2f726361cf2 100644 --- a/apps/builder/app/shared/nano-states/misc.ts +++ b/apps/builder/app/shared/nano-states/misc.ts @@ -19,7 +19,6 @@ import type { Style } from "@webstudio-is/css-engine"; import type { Project } from "@webstudio-is/project"; import type { MarketplaceProduct } from "@webstudio-is/project-build"; import type { TokenPermissions } from "@webstudio-is/authorization-token"; -import { createImageLoader, type ImageLoader } from "@webstudio-is/image"; import type { DragStartPayload } from "~/canvas/shared/use-drag-drop"; import { type InstanceSelector } from "../tree-utils"; import type { HtmlTags } from "html-tags"; @@ -35,8 +34,6 @@ export const $project = atom(); export const $publisherHost = atom("wstd.work"); -export const $imageLoader = atom(createImageLoader({})); - export const $publishedOrigin = computed( [$project, $publisherHost], (project, publisherHost) => `https://${project?.domain}.${publisherHost}` diff --git a/packages/cli/src/prebuild.ts b/packages/cli/src/prebuild.ts index 7cae6fa35e85..e4af2bfedcad 100644 --- a/packages/cli/src/prebuild.ts +++ b/packages/cli/src/prebuild.ts @@ -49,7 +49,7 @@ import { replaceFormActionsWithResources, } from "@webstudio-is/sdk"; import type { Data } from "@webstudio-is/http-client"; -import { createImageLoader } from "@webstudio-is/image"; +import { wsImageLoader } from "@webstudio-is/image"; import { LOCAL_DATA_FILE } from "./config"; import { createFileIfNotExists, @@ -447,11 +447,10 @@ export const prebuild = async (options: { } const assetOrigin = `https://${domain}.${appDomain}`; - const imageLoader = createImageLoader({}); for (const asset of siteData.assets) { if (asset.type === "image") { - const imagePath = imageLoader({ + const imagePath = wsImageLoader({ src: asset.name, format: "raw", }); diff --git a/packages/image/src/image-dev.stories.tsx b/packages/image/src/image-dev.stories.tsx index 8a11a4d4e045..b54dac9745ae 100644 --- a/packages/image/src/image-dev.stories.tsx +++ b/packages/image/src/image-dev.stories.tsx @@ -2,7 +2,7 @@ import type * as React from "react"; import type { Meta, StoryFn } from "@storybook/react"; -import { Image as ImagePrimitive, createImageLoader } from "./"; +import { Image as ImagePrimitive, wsImageLoader } from "./"; // to not allow include local assets everywhere, just enable it for this file // eslint-disable-next-line @typescript-eslint/ban-ts-comment @@ -29,12 +29,6 @@ const imageSrc = USE_CLOUDFLARE_IMAGE_TRANSFORM ? REMOTE_SELF_DOMAIN_IMAGE : localLogoImage; -const imageLoader = createImageLoader({ - imageBaseUrl: USE_CLOUDFLARE_IMAGE_TRANSFORM - ? "https://webstudio.is/cdn-cgi/image/" - : "", -}); - const ImageBase: StoryFn< React.ForwardRefExoticComponent< Omit & { @@ -52,7 +46,7 @@ const ImageBase: StoryFn< ); diff --git a/packages/image/src/image-loader.test.ts b/packages/image/src/image-loader.test.ts index 8211b3c66b00..1de820301006 100644 --- a/packages/image/src/image-loader.test.ts +++ b/packages/image/src/image-loader.test.ts @@ -1,5 +1,5 @@ import { describe, test, expect } from "vitest"; -import { createImageLoader } from "./image-loaders"; +import { wsImageLoader } from "./image-loaders"; const decodePathFragment = (fragment: string) => { return decodeURIComponent(fragment); @@ -12,10 +12,9 @@ const encodePathFragment = (fragment: string) => { describe("Asset image transforms", () => { test("width is number", () => { const imageBaseUrl = "/cgi/image/"; - const loader = createImageLoader({}); const assetName = "Привет_Мир__2F__BQNEuP8O9N79eVwPfbBJg.webp"; - const result = loader({ + const result = wsImageLoader({ width: 128, src: assetName, quality: 100, @@ -36,11 +35,10 @@ describe("Asset image transforms", () => { describe("Remote src image transforms", () => { test("width is number", () => { const imageBaseUrl = "/cgi/image/"; - const loader = createImageLoader({}); const remoteSrc = "https://example.com/lo%3Fgo.webp?a=1"; - const result = loader({ + const result = wsImageLoader({ width: 128, src: remoteSrc, quality: 100, @@ -61,13 +59,12 @@ describe("Remote src image transforms", () => { test("Double encoded fragment", () => { const imageBaseUrl = "/cgi/image/"; - const loader = createImageLoader({}); const remoteSrc = encodePathFragment( "https://ex%2Fample.com/lo%3Fgo.webp?a=1" ); - const result = loader({ + const result = wsImageLoader({ width: 128, src: remoteSrc, quality: 100, diff --git a/packages/image/src/image-loaders.ts b/packages/image/src/image-loaders.ts index 01570dc92860..56bb619f8f51 100644 --- a/packages/image/src/image-loaders.ts +++ b/packages/image/src/image-loaders.ts @@ -1,10 +1,6 @@ import warnOnce from "warn-once"; import { allSizes, type ImageLoader } from "./image-optimize"; -export type ImageLoaderOptions = { - imageBaseUrl?: string; -}; - const NON_EXISTING_DOMAIN = "https://a3cbcbec-cdb1-4ea4-ad60-43c795308ddc.ddc"; const joinPath = (...segments: string[]) => { @@ -22,42 +18,48 @@ const encodePathFragment = (fragment: string) => { * Default image loader in case of no loader provided * https://developers.cloudflare.com/images/image-resizing/url-format/ **/ -export const createImageLoader = - (_loaderOptions: ImageLoaderOptions): ImageLoader => - (props) => { - const width = props.format === "raw" ? 16 : props.width; - const quality = props.format === "raw" ? 100 : props.quality; - const { format, src } = props; - - if (process.env.NODE_ENV !== "production") { - warnOnce( - allSizes.includes(width) === false, - "Width must be only from allowed values" - ); - } +export const wsImageLoader: ImageLoader = (props) => { + const width = props.format === "raw" ? 16 : props.width; + const quality = props.format === "raw" ? 100 : props.quality; + const { format, src } = props; - const resultUrl = new URL("/cgi/image/", NON_EXISTING_DOMAIN); + if (process.env.NODE_ENV !== "production") { + warnOnce( + allSizes.includes(width) === false, + "Width must be only from allowed values" + ); + } - if (format !== "raw") { - resultUrl.searchParams.set("width", width.toString()); - resultUrl.searchParams.set("quality", quality.toString()); + const resultUrl = new URL("/cgi/image/", NON_EXISTING_DOMAIN); - if (props.height != null) { - resultUrl.searchParams.set("height", props.height.toString()); - } + if (format !== "raw") { + resultUrl.searchParams.set("width", width.toString()); + resultUrl.searchParams.set("quality", quality.toString()); - if (props.fit != null) { - resultUrl.searchParams.set("fit", props.fit); - } + if (props.height != null) { + resultUrl.searchParams.set("height", props.height.toString()); } - resultUrl.searchParams.set("format", format ?? "auto"); - - resultUrl.pathname = joinPath(resultUrl.pathname, encodePathFragment(src)); - if (resultUrl.href.startsWith(NON_EXISTING_DOMAIN)) { - return `${resultUrl.pathname}?${resultUrl.searchParams.toString()}`; + if (props.fit != null) { + resultUrl.searchParams.set("fit", props.fit); } + } + resultUrl.searchParams.set("format", format ?? "auto"); + + resultUrl.pathname = joinPath(resultUrl.pathname, encodePathFragment(src)); + + if (resultUrl.href.startsWith(NON_EXISTING_DOMAIN)) { + return `${resultUrl.pathname}?${resultUrl.searchParams.toString()}`; + } + + // Cloudflare docs say that we don't need to urlencode the path params + return resultUrl.href; +}; + +type ImageLoaderOptions = { + imageBaseUrl?: string; +}; - // Cloudflare docs say that we don't need to urlencode the path params - return resultUrl.href; - }; +export const createImageLoader = ( + _loaderOptions: ImageLoaderOptions +): ImageLoader => wsImageLoader; diff --git a/packages/image/src/image-optimize.test.ts b/packages/image/src/image-optimize.test.ts index 67d0f9e2bd36..7463b8cceaa3 100644 --- a/packages/image/src/image-optimize.test.ts +++ b/packages/image/src/image-optimize.test.ts @@ -1,6 +1,6 @@ import { describe, test, expect } from "vitest"; import { getImageAttributes } from "./image-optimize"; -import { createImageLoader } from "./image-loaders"; +import { wsImageLoader } from "./image-loaders"; describe("Image optimizations applied", () => { test("width is number, create pixel density descriptor 'x'", () => { @@ -11,7 +11,7 @@ describe("Image optimizations applied", () => { srcSet: undefined, sizes: undefined, quality: 100, - loader: createImageLoader({}), + loader: wsImageLoader, }); expect(imgAttr).toMatchInlineSnapshot(` @@ -31,7 +31,7 @@ describe("Image optimizations applied", () => { srcSet: undefined, sizes: undefined, quality: 100, - loader: createImageLoader({}), + loader: wsImageLoader, }); expect(imgAttr).toMatchInlineSnapshot(` @@ -51,7 +51,7 @@ describe("Image optimizations applied", () => { srcSet: undefined, sizes: undefined, quality: 90, - loader: createImageLoader({}), + loader: wsImageLoader, }); expect(imgAttr).toMatchInlineSnapshot(` @@ -71,7 +71,7 @@ describe("Image optimizations applied", () => { srcSet: undefined, sizes: "100vw", quality: 70, - loader: createImageLoader({}), + loader: wsImageLoader, }); expect(imgAttr).toMatchInlineSnapshot(` @@ -91,7 +91,7 @@ describe("Image optimizations applied", () => { srcSet: undefined, sizes: "100vw", quality: 70, - loader: createImageLoader({}), + loader: wsImageLoader, }); expect(imgAttr).toMatchInlineSnapshot(` @@ -136,7 +136,7 @@ describe("Image optimizations not applied", () => { srcSet: undefined, sizes: undefined, quality: 100, - loader: createImageLoader({}), + loader: wsImageLoader, }); expect(imgAttr).toMatchInlineSnapshot(` @@ -154,7 +154,7 @@ describe("Image optimizations not applied", () => { srcSet: undefined, sizes: undefined, quality: 100, - loader: createImageLoader({}), + loader: wsImageLoader, }); expect(imgAttr).toMatchInlineSnapshot(` @@ -172,7 +172,7 @@ describe("Image optimizations not applied", () => { srcSet: "user-defined-srcset", sizes: undefined, quality: 100, - loader: createImageLoader({}), + loader: wsImageLoader, }); expect(imgAttr).toMatchInlineSnapshot(` @@ -191,7 +191,7 @@ describe("Image optimizations not applied", () => { srcSet: undefined, sizes: undefined, quality: 100, - loader: createImageLoader({}), + loader: wsImageLoader, }); expect(imgAttr).toMatchInlineSnapshot(`undefined`); @@ -205,7 +205,7 @@ describe("Image optimizations not applied", () => { srcSet: undefined, sizes: undefined, quality: 100, - loader: createImageLoader({}), + loader: wsImageLoader, }); expect(imgAttr).toMatchInlineSnapshot(`undefined`);