@slopmachine/react 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @slopmachine/react
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 25bf4d8: Remove quality prop and query parameter across SDK and components.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [25bf4d8]
12
+ - @slopmachine/core@0.4.0
13
+
3
14
  ## 0.3.0
4
15
 
5
16
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -47,7 +47,7 @@ interface SlopImageProps extends Omit<React.ImgHTMLAttributes<HTMLImageElement>,
47
47
  * />
48
48
  * ```
49
49
  *
50
- * @version 0.3.0
50
+ * @version 0.4.0
51
51
  */
52
52
  declare const SlopImage: React.FC<SlopImageProps>;
53
53
 
@@ -90,7 +90,7 @@ interface SlopVideoProps extends Omit<React.VideoHTMLAttributes<HTMLVideoElement
90
90
  * />
91
91
  * ```
92
92
  *
93
- * @version 0.3.0
93
+ * @version 0.4.0
94
94
  */
95
95
  declare const SlopVideo: React.FC<SlopVideoProps>;
96
96
 
@@ -128,7 +128,7 @@ interface SlopTextProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "chil
128
128
  * />
129
129
  * ```
130
130
  *
131
- * @version 0.3.0
131
+ * @version 0.4.0
132
132
  */
133
133
  declare const SlopText: React.ForwardRefExoticComponent<SlopTextProps & React.RefAttributes<HTMLDivElement>>;
134
134
 
package/dist/index.d.ts CHANGED
@@ -47,7 +47,7 @@ interface SlopImageProps extends Omit<React.ImgHTMLAttributes<HTMLImageElement>,
47
47
  * />
48
48
  * ```
49
49
  *
50
- * @version 0.3.0
50
+ * @version 0.4.0
51
51
  */
52
52
  declare const SlopImage: React.FC<SlopImageProps>;
53
53
 
@@ -90,7 +90,7 @@ interface SlopVideoProps extends Omit<React.VideoHTMLAttributes<HTMLVideoElement
90
90
  * />
91
91
  * ```
92
92
  *
93
- * @version 0.3.0
93
+ * @version 0.4.0
94
94
  */
95
95
  declare const SlopVideo: React.FC<SlopVideoProps>;
96
96
 
@@ -128,7 +128,7 @@ interface SlopTextProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "chil
128
128
  * />
129
129
  * ```
130
130
  *
131
- * @version 0.3.0
131
+ * @version 0.4.0
132
132
  */
133
133
  declare const SlopText: React.ForwardRefExoticComponent<SlopTextProps & React.RefAttributes<HTMLDivElement>>;
134
134
 
package/dist/index.js CHANGED
@@ -56,7 +56,6 @@ var SlopImage = ({
56
56
  aspectRatio = "1:1",
57
57
  version,
58
58
  resultId,
59
- quality = "fast",
60
59
  variables = {},
61
60
  baseUrl,
62
61
  original,
@@ -81,7 +80,6 @@ var SlopImage = ({
81
80
  resultId,
82
81
  variables,
83
82
  baseUrl,
84
- quality,
85
83
  original,
86
84
  attachments
87
85
  }),
@@ -96,7 +94,6 @@ var SlopImage = ({
96
94
  resultId,
97
95
  variables,
98
96
  baseUrl,
99
- quality,
100
97
  original,
101
98
  attachments
102
99
  ]
@@ -355,7 +352,6 @@ var SlopVideo = ({
355
352
  aspectRatio = "16:9",
356
353
  version,
357
354
  resultId,
358
- quality = "fast",
359
355
  variables = {},
360
356
  duration,
361
357
  baseUrl,
@@ -383,7 +379,6 @@ var SlopVideo = ({
383
379
  variables,
384
380
  duration,
385
381
  baseUrl,
386
- quality,
387
382
  original,
388
383
  attachments
389
384
  }),
@@ -399,7 +394,6 @@ var SlopVideo = ({
399
394
  variables,
400
395
  duration,
401
396
  baseUrl,
402
- quality,
403
397
  original,
404
398
  attachments
405
399
  ]
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/components/SlopImage.tsx","../src/components/SlopVideo.tsx","../src/components/SlopText.tsx"],"sourcesContent":["export { SlopImage, type SlopImageProps } from \"./components/SlopImage\";\nexport { SlopVideo, type SlopVideoProps } from \"./components/SlopVideo\";\nexport { SlopText, type SlopTextProps } from \"./components/SlopText\";\n\nexport type {\n ImageAspectRatio,\n VideoAspectRatio,\n SlopImageOptions,\n SlopVideoOptions,\n} from \"@slopmachine/core\";\n\nexport { preloadImage } from \"@slopmachine/core\";\n","import React, { useMemo, useState } from \"react\";\nimport { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nimport {\n buildImageUrl,\n type SlopImageOptions,\n type ImageAspectRatio,\n} from \"@slopmachine/core\";\n\n// Utility for Tailwind classes\nfunction cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport interface SlopImageProps\n extends\n Omit<React.ImgHTMLAttributes<HTMLImageElement>, \"src\" | \"alt\">,\n Omit<SlopImageOptions, \"aspectRatio\"> {\n /**\n * The aspect ratio of the generated image. Defaults to \"1:1\".\n */\n aspectRatio?: ImageAspectRatio;\n /**\n * Custom React node to display while the image is loading.\n * If not provided, a default spinner and shimmer effect will be shown.\n */\n loader?: React.ReactNode;\n /**\n * How the image should be resized to fit its container. Defaults to \"cover\".\n */\n objectFit?: React.CSSProperties[\"objectFit\"];\n /**\n * Additional CSS classes to apply directly to the `<img />` element.\n */\n imageClassName?: string;\n}\n\n/**\n * Renders an image generated by Slop Machine.\n *\n * This component automatically constructs the correct URL for the Slop Machine API,\n * displays a loading skeleton or custom loader while fetching, and handles errors.\n *\n * @example\n * ```tsx\n * // Using a Bucket\n * <SlopImage\n * bucketId=\"my-bucket\"\n * resultId=\"some-result\"\n * aspectRatio=\"16:9\"\n * className=\"rounded-lg\"\n * objectFit=\"cover\"\n * />\n *\n * // Using a Pipeline with runtime prompt\n * <SlopImage\n * pipelineId=\"pipe_live_abc123\"\n * prompt=\"1960s retro robot eating pizza on Mars\"\n * aspectRatio=\"16:9\"\n * metadata={{ userId: \"123\" }}\n * />\n * ```\n *\n * @version 0.3.0\n */\nexport const SlopImage: React.FC<SlopImageProps> = ({\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n className,\n aspectRatio = \"1:1\",\n version,\n resultId,\n quality = \"fast\",\n variables = {},\n baseUrl,\n original,\n attachments,\n loader,\n objectFit = \"cover\",\n imageClassName,\n style,\n onLoad,\n onError,\n ...props\n}) => {\n // Construct API URL\n const rawSrc = useMemo(\n () =>\n buildImageUrl({\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n aspectRatio,\n version,\n resultId,\n variables,\n baseUrl,\n quality,\n original,\n attachments,\n }),\n [\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n aspectRatio,\n version,\n resultId,\n variables,\n baseUrl,\n quality,\n original,\n attachments,\n ],\n );\n\n const [src, setSrc] = useState(rawSrc);\n\n React.useEffect(() => {\n const timer = setTimeout(() => {\n setSrc(rawSrc);\n }, 100);\n return () => clearTimeout(timer);\n }, [rawSrc]);\n\n const alt = \"Image produced by Slop Machine (slopmachine.dev)\";\n\n const [isLoading, setIsLoading] = useState(true);\n const [currentSrc, setCurrentSrc] = useState(src);\n\n if (src !== currentSrc) {\n setCurrentSrc(src);\n setIsLoading(true);\n }\n\n React.useEffect(() => {\n if (!src) return;\n\n fetch(src, { method: \"HEAD\" })\n .then(async (res) => {\n if (!res.ok) {\n let errorMessage = res.statusText;\n try {\n const errRes = await fetch(src);\n const errorText = await errRes.text();\n const errorData = JSON.parse(errorText);\n if (errorData.error) {\n errorMessage = errorData.error;\n }\n } catch (e) {\n // Failed to fetch or parse error details\n }\n console.error(\"SlopImage error:\", res.status, errorMessage);\n setIsLoading(false);\n }\n })\n .catch((err) => {\n console.error(`Error fetching image from ${src}:`, err);\n setIsLoading(false);\n });\n }, [src]);\n\n return (\n <>\n <style>{`\n @keyframes slop-shimmer {\n 0% {\n background-position: 200% 0;\n }\n 100% {\n background-position: -200% 0;\n }\n }\n @keyframes slop-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n `}</style>\n <div className={className} style={style}>\n <div\n className=\"slop-wrapper relative overflow-hidden w-full h-full\"\n style={{\n aspectRatio: String(aspectRatio).replace(\":\", \"/\"),\n position: \"relative\",\n overflow: \"hidden\",\n width: \"100%\",\n height: \"100%\",\n }}\n >\n {/* Loading UI */}\n {loader ? (\n <div\n className={cn(\n \"absolute inset-0 z-10 flex items-center justify-center transition-opacity duration-300\",\n isLoading ? \"opacity-100\" : \"opacity-0 pointer-events-none\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n opacity: isLoading ? 1 : 0,\n pointerEvents: isLoading ? \"auto\" : \"none\",\n transition: \"opacity 300ms ease-in-out\",\n }}\n >\n {loader}\n </div>\n ) : (\n <>\n {/* Loading overlay */}\n <div\n className={cn(\n \"absolute inset-0 z-10 flex items-center justify-center bg-muted transition-opacity duration-300\",\n isLoading ? \"opacity-100\" : \"opacity-0 pointer-events-none\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"var(--muted, #f3f4f6)\",\n opacity: isLoading ? 1 : 0,\n pointerEvents: isLoading ? \"auto\" : \"none\",\n transition: \"opacity 300ms ease-in-out\",\n }}\n >\n <div\n className=\"flex flex-col items-center gap-2\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"0.5rem\",\n }}\n >\n <svg\n className=\"spinner size-6 text-muted-foreground\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n style={{\n width: \"24px\",\n height: \"24px\",\n color: \"var(--muted-foreground, #6b7280)\",\n animation: \"slop-spin 1s linear infinite\",\n }}\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n style={{ opacity: 0.25 }}\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n style={{ opacity: 0.75 }}\n />\n </svg>\n <span\n className=\"text-xs text-muted-foreground\"\n style={{\n fontSize: \"0.75rem\",\n color: \"var(--muted-foreground, #6b7280)\",\n }}\n >\n Loading...\n </span>\n </div>\n </div>\n\n {/* Shimmer effect underneath */}\n <div\n className={cn(\n \"shimmer-effect absolute inset-0 bg-gradient-to-r from-muted via-muted/50 to-muted\",\n isLoading ? \"opacity-100\" : \"opacity-0\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n background:\n \"linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)\",\n backgroundSize: \"200% 100%\",\n animation: \"slop-shimmer 2s ease-in-out infinite\",\n opacity: isLoading ? 1 : 0,\n transition: \"opacity 300ms\",\n }}\n />\n </>\n )}\n\n {/* Image */}\n <img\n key={src}\n src={src}\n alt={alt}\n {...props}\n onLoad={(e) => {\n setIsLoading(false);\n onLoad?.(e);\n }}\n onError={(e) => {\n setIsLoading(false);\n onError?.(e);\n }}\n className={cn(\n \"h-full w-full transition-opacity duration-500\",\n isLoading ? \"opacity-0\" : \"opacity-100\",\n imageClassName,\n )}\n style={{\n height: \"100%\",\n width: \"100%\",\n objectFit,\n transition: \"opacity 500ms\",\n opacity: isLoading ? 0 : 1,\n }}\n />\n </div>\n </div>\n </>\n );\n};\n","import React, { useMemo, useState, useRef, useEffect } from \"react\";\nimport { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nimport {\n buildVideoUrl,\n type SlopVideoOptions,\n type VideoAspectRatio,\n} from \"@slopmachine/core\";\n\n// Utility for Tailwind classes\nfunction cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport interface SlopVideoProps\n extends\n Omit<React.VideoHTMLAttributes<HTMLVideoElement>, \"src\">,\n Omit<SlopVideoOptions, \"aspectRatio\"> {\n /**\n * The aspect ratio of the generated video. Defaults to \"16:9\".\n */\n aspectRatio?: VideoAspectRatio;\n /**\n * Custom React node to display while the video is loading.\n * If not provided, a default spinner and shimmer effect will be shown.\n */\n loader?: React.ReactNode;\n}\n\n/**\n * Renders a video generated by Slop Machine.\n *\n * This component automatically constructs the correct URL for the Slop Machine API,\n * displays a loading skeleton or custom loader while fetching, and handles errors.\n *\n * @example\n * ```tsx\n * // Using a Bucket\n * <SlopVideo\n * bucketId=\"my-bucket\"\n * resultId=\"some-result\"\n * aspectRatio=\"16:9\"\n * className=\"rounded-lg\"\n * autoPlay\n * loop\n * muted\n * />\n *\n * // Using a Pipeline with runtime prompt\n * <SlopVideo\n * pipelineId=\"pipe_live_abc123\"\n * prompt=\"Drone shot of a cyberpunk city in rain\"\n * aspectRatio=\"16:9\"\n * metadata={{ campaign: \"spring_launch\" }}\n * />\n * ```\n *\n * @version 0.3.0\n */\nexport const SlopVideo: React.FC<SlopVideoProps> = ({\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n className,\n aspectRatio = \"16:9\",\n version,\n resultId,\n quality = \"fast\",\n variables = {},\n duration,\n baseUrl,\n original,\n attachments,\n loader,\n autoPlay = true,\n loop = true,\n muted = true,\n playsInline = true,\n onLoadedData,\n onError,\n ...props\n}) => {\n // Construct API URL\n const rawSrc = useMemo(\n () =>\n buildVideoUrl({\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n aspectRatio,\n version,\n resultId,\n variables,\n duration,\n baseUrl,\n quality,\n original,\n attachments,\n }),\n [\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n aspectRatio,\n version,\n resultId,\n variables,\n duration,\n baseUrl,\n quality,\n original,\n attachments,\n ],\n );\n\n const [src, setSrc] = useState(rawSrc);\n\n useEffect(() => {\n const timer = setTimeout(() => {\n setSrc(rawSrc);\n }, 100);\n return () => clearTimeout(timer);\n }, [rawSrc]);\n\n const [isLoading, setIsLoading] = useState(true);\n const [currentSrc, setCurrentSrc] = useState(src);\n const videoRef = useRef<HTMLVideoElement>(null);\n\n if (src !== currentSrc) {\n setCurrentSrc(src);\n setIsLoading(true);\n }\n\n useEffect(() => {\n if (!src) return;\n\n fetch(src, { method: \"HEAD\" })\n .then(async (res) => {\n if (!res.ok) {\n let errorMessage = res.statusText;\n try {\n const errRes = await fetch(src);\n const errorText = await errRes.text();\n const errorData = JSON.parse(errorText);\n if (errorData.error) {\n errorMessage = errorData.error;\n }\n } catch (e) {\n // Failed to fetch or parse error details\n }\n console.error(\"SlopVideo error:\", res.status, errorMessage);\n setIsLoading(false);\n }\n })\n .catch((err) => {\n console.error(`Error fetching video from ${src}:`, err);\n setIsLoading(false);\n });\n }, [src]);\n\n return (\n <>\n <style>{`\n @keyframes slop-shimmer {\n 0% {\n background-position: 200% 0;\n }\n 100% {\n background-position: -200% 0;\n }\n }\n @keyframes slop-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n `}</style>\n <div className={className} style={props.style}>\n <div\n className=\"slop-wrapper relative overflow-hidden w-full h-full\"\n style={{\n aspectRatio: String(aspectRatio).replace(\":\", \"/\"),\n position: \"relative\",\n overflow: \"hidden\",\n width: \"100%\",\n height: \"100%\",\n }}\n >\n {/* Loading UI */}\n {loader ? (\n <div\n className={cn(\n \"absolute inset-0 z-10 flex items-center justify-center transition-opacity duration-300\",\n isLoading ? \"opacity-100\" : \"opacity-0 pointer-events-none\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n opacity: isLoading ? 1 : 0,\n pointerEvents: isLoading ? \"auto\" : \"none\",\n transition: \"opacity 300ms ease-in-out\",\n }}\n >\n {loader}\n </div>\n ) : (\n <>\n {/* Loading overlay */}\n <div\n className={cn(\n \"absolute inset-0 z-10 flex items-center justify-center bg-muted transition-opacity duration-300\",\n isLoading ? \"opacity-100\" : \"opacity-0 pointer-events-none\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"var(--muted, #f3f4f6)\",\n opacity: isLoading ? 1 : 0,\n pointerEvents: isLoading ? \"auto\" : \"none\",\n transition: \"opacity 300ms ease-in-out\",\n }}\n >\n <div\n className=\"flex flex-col items-center gap-2\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"0.5rem\",\n }}\n >\n <svg\n className=\"spinner size-6 text-muted-foreground\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n style={{\n width: \"24px\",\n height: \"24px\",\n color: \"var(--muted-foreground, #6b7280)\",\n animation: \"slop-spin 1s linear infinite\",\n }}\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n style={{ opacity: 0.25 }}\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n style={{ opacity: 0.75 }}\n />\n </svg>\n <span\n className=\"text-xs text-muted-foreground\"\n style={{\n fontSize: \"0.75rem\",\n color: \"var(--muted-foreground, #6b7280)\",\n }}\n >\n Loading...\n </span>\n </div>\n </div>\n\n {/* Shimmer effect underneath */}\n <div\n className={cn(\n \"shimmer-effect absolute inset-0 bg-gradient-to-r from-muted via-muted/50 to-muted\",\n isLoading ? \"opacity-100\" : \"opacity-0\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n background:\n \"linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)\",\n backgroundSize: \"200% 100%\",\n animation: \"slop-shimmer 2s ease-in-out infinite\",\n opacity: isLoading ? 1 : 0,\n transition: \"opacity 300ms\",\n }}\n />\n </>\n )}\n\n {/* Video */}\n <video\n key={src}\n ref={videoRef}\n src={src}\n autoPlay={autoPlay}\n loop={loop}\n muted={muted}\n playsInline={playsInline}\n {...props}\n onLoadedData={(e) => {\n setIsLoading(false);\n onLoadedData?.(e);\n }}\n onError={(e) => {\n setIsLoading(false);\n onError?.(e);\n }}\n className={cn(\n \"h-full w-full object-cover transition-opacity duration-500\",\n isLoading ? \"opacity-0\" : \"opacity-100\",\n )}\n style={{\n height: \"100%\",\n width: \"100%\",\n objectFit: \"cover\",\n transition: \"opacity 500ms\",\n opacity: isLoading ? 0 : 1,\n }}\n />\n </div>\n </div>\n </>\n );\n};\n","import React, { useEffect, useMemo, useState } from \"react\";\nimport { buildTextUrl, type SlopTextOptions } from \"@slopmachine/core\";\nimport { marked } from \"marked\";\n\nexport interface SlopTextProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, \"children\">,\n SlopTextOptions {\n /**\n * Optional loading component to show while the text is being generated\n */\n fallback?: React.ReactNode;\n /**\n * Optional error component to show if the text generation fails\n */\n errorFallback?: React.ReactNode;\n}\n\n/**\n * Renders text generated by Slop Machine.\n *\n * This component automatically constructs the correct URL for the Slop Machine API,\n * fetches the generated text, and displays it with optional loading and error states.\n *\n * @example\n * ```tsx\n * // Using a Bucket\n * <SlopText\n * bucketId=\"my-text-bucket\"\n * fallback={<div>Loading story...</div>}\n * errorFallback={<div>Failed to load story</div>}\n * className=\"text-lg text-gray-800\"\n * />\n *\n * // Using a Pipeline with runtime prompt\n * <SlopText\n * pipelineId=\"pipe_live_abc123\"\n * prompt=\"Write a whimsical haiku about quantum physics\"\n * metadata={{ userId: \"123\" }}\n * />\n * ```\n *\n * @version 0.3.0\n */\nexport const SlopText = React.forwardRef<HTMLDivElement, SlopTextProps>(\n (\n {\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n version,\n resultId,\n variables,\n baseUrl,\n attachments,\n fallback,\n errorFallback,\n ...props\n },\n ref,\n ) => {\n const [text, setText] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const rawUrl = useMemo(\n () =>\n buildTextUrl({\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n version,\n resultId,\n variables,\n baseUrl,\n attachments,\n }),\n [\n bucketId,\n pipelineId,\n siloId,\n prompt,\n JSON.stringify(metadata),\n version,\n resultId,\n JSON.stringify(variables),\n baseUrl,\n JSON.stringify(attachments),\n ],\n );\n\n useEffect(() => {\n let isMounted = true;\n\n const fetchText = async () => {\n try {\n setLoading(true);\n setError(null);\n\n // Fetch the URL to get the content, following redirects automatically\n const response = await fetch(rawUrl, { cache: \"no-store\" });\n if (!response.ok) {\n let errorMessage = response.statusText;\n try {\n const errorText = await response.text();\n const errorData = JSON.parse(errorText);\n if (errorData.error) {\n errorMessage = errorData.error;\n }\n } catch (e) {\n // Ignore JSON parse errors if the response isn't JSON\n }\n throw new Error(`Failed to fetch text: ${errorMessage}`);\n }\n const content = await response.text();\n if (isMounted) {\n setText(content);\n }\n } catch (err) {\n if (isMounted) {\n const finalError =\n err instanceof Error ? err : new Error(\"Failed to generate text\");\n console.error(finalError);\n setError(finalError);\n }\n } finally {\n if (isMounted) {\n setLoading(false);\n }\n }\n };\n\n fetchText();\n\n return () => {\n isMounted = false;\n };\n }, [rawUrl]);\n\n if (error && errorFallback) {\n return <>{errorFallback}</>;\n }\n\n if (loading) {\n if (fallback) {\n return <>{fallback}</>;\n }\n return (\n <div className={props.className} style={props.style}>\n <style>{`\n @keyframes slop-shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n }\n @keyframes slop-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n `}</style>\n <div\n className=\"slop-wrapper relative overflow-hidden w-full\"\n style={{\n position: \"relative\",\n overflow: \"hidden\",\n width: \"100%\",\n minHeight: \"100px\",\n }}\n >\n {/* Loading overlay */}\n <div\n className=\"absolute inset-0 z-10 flex items-center justify-center bg-muted transition-opacity duration-300\"\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"var(--muted, #f3f4f6)\",\n }}\n >\n <div\n className=\"flex flex-col items-center gap-2\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"0.5rem\",\n }}\n >\n <svg\n className=\"spinner size-6 text-muted-foreground\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n style={{\n width: \"24px\",\n height: \"24px\",\n color: \"var(--muted-foreground, #6b7280)\",\n animation: \"slop-spin 1s linear infinite\",\n }}\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n style={{ opacity: 0.25 }}\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n style={{ opacity: 0.75 }}\n />\n </svg>\n <span\n className=\"text-xs text-muted-foreground\"\n style={{\n fontSize: \"0.75rem\",\n color: \"var(--muted-foreground, #6b7280)\",\n }}\n >\n Loading...\n </span>\n </div>\n </div>\n\n {/* Shimmer effect underneath */}\n <div\n className=\"shimmer-effect absolute inset-0 bg-gradient-to-r from-muted via-muted/50 to-muted\"\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n background:\n \"linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)\",\n backgroundSize: \"200% 100%\",\n animation: \"slop-shimmer 2s ease-in-out infinite\",\n }}\n />\n </div>\n </div>\n );\n }\n\n return (\n <div\n ref={ref}\n {...props}\n dangerouslySetInnerHTML={{\n __html: text ? (marked.parse(text) as string) : \"\",\n }}\n />\n );\n },\n);\n\nSlopText.displayName = \"SlopText\";\n"],"mappings":"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","names":["React","import_react","import_clsx","import_tailwind_merge","import_core","import_jsx_runtime","cn","import_react","import_core","import_jsx_runtime","React","import_core"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/components/SlopImage.tsx","../src/components/SlopVideo.tsx","../src/components/SlopText.tsx"],"sourcesContent":["export { SlopImage, type SlopImageProps } from \"./components/SlopImage\";\nexport { SlopVideo, type SlopVideoProps } from \"./components/SlopVideo\";\nexport { SlopText, type SlopTextProps } from \"./components/SlopText\";\n\nexport type {\n ImageAspectRatio,\n VideoAspectRatio,\n SlopImageOptions,\n SlopVideoOptions,\n} from \"@slopmachine/core\";\n\nexport { preloadImage } from \"@slopmachine/core\";\n","import React, { useMemo, useState } from \"react\";\nimport { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nimport {\n buildImageUrl,\n type SlopImageOptions,\n type ImageAspectRatio,\n} from \"@slopmachine/core\";\n\n// Utility for Tailwind classes\nfunction cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport interface SlopImageProps\n extends\n Omit<React.ImgHTMLAttributes<HTMLImageElement>, \"src\" | \"alt\">,\n Omit<SlopImageOptions, \"aspectRatio\"> {\n /**\n * The aspect ratio of the generated image. Defaults to \"1:1\".\n */\n aspectRatio?: ImageAspectRatio;\n /**\n * Custom React node to display while the image is loading.\n * If not provided, a default spinner and shimmer effect will be shown.\n */\n loader?: React.ReactNode;\n /**\n * How the image should be resized to fit its container. Defaults to \"cover\".\n */\n objectFit?: React.CSSProperties[\"objectFit\"];\n /**\n * Additional CSS classes to apply directly to the `<img />` element.\n */\n imageClassName?: string;\n}\n\n/**\n * Renders an image generated by Slop Machine.\n *\n * This component automatically constructs the correct URL for the Slop Machine API,\n * displays a loading skeleton or custom loader while fetching, and handles errors.\n *\n * @example\n * ```tsx\n * // Using a Bucket\n * <SlopImage\n * bucketId=\"my-bucket\"\n * resultId=\"some-result\"\n * aspectRatio=\"16:9\"\n * className=\"rounded-lg\"\n * objectFit=\"cover\"\n * />\n *\n * // Using a Pipeline with runtime prompt\n * <SlopImage\n * pipelineId=\"pipe_live_abc123\"\n * prompt=\"1960s retro robot eating pizza on Mars\"\n * aspectRatio=\"16:9\"\n * metadata={{ userId: \"123\" }}\n * />\n * ```\n *\n * @version 0.4.0\n */\nexport const SlopImage: React.FC<SlopImageProps> = ({\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n className,\n aspectRatio = \"1:1\",\n version,\n resultId,\n variables = {},\n baseUrl,\n original,\n attachments,\n loader,\n objectFit = \"cover\",\n imageClassName,\n style,\n onLoad,\n onError,\n ...props\n}) => {\n // Construct API URL\n const rawSrc = useMemo(\n () =>\n buildImageUrl({\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n aspectRatio,\n version,\n resultId,\n variables,\n baseUrl,\n original,\n attachments,\n }),\n [\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n aspectRatio,\n version,\n resultId,\n variables,\n baseUrl,\n original,\n attachments,\n ],\n );\n\n const [src, setSrc] = useState(rawSrc);\n\n React.useEffect(() => {\n const timer = setTimeout(() => {\n setSrc(rawSrc);\n }, 100);\n return () => clearTimeout(timer);\n }, [rawSrc]);\n\n const alt = \"Image produced by Slop Machine (slopmachine.dev)\";\n\n const [isLoading, setIsLoading] = useState(true);\n const [currentSrc, setCurrentSrc] = useState(src);\n\n if (src !== currentSrc) {\n setCurrentSrc(src);\n setIsLoading(true);\n }\n\n React.useEffect(() => {\n if (!src) return;\n\n fetch(src, { method: \"HEAD\" })\n .then(async (res) => {\n if (!res.ok) {\n let errorMessage = res.statusText;\n try {\n const errRes = await fetch(src);\n const errorText = await errRes.text();\n const errorData = JSON.parse(errorText);\n if (errorData.error) {\n errorMessage = errorData.error;\n }\n } catch (e) {\n // Failed to fetch or parse error details\n }\n console.error(\"SlopImage error:\", res.status, errorMessage);\n setIsLoading(false);\n }\n })\n .catch((err) => {\n console.error(`Error fetching image from ${src}:`, err);\n setIsLoading(false);\n });\n }, [src]);\n\n return (\n <>\n <style>{`\n @keyframes slop-shimmer {\n 0% {\n background-position: 200% 0;\n }\n 100% {\n background-position: -200% 0;\n }\n }\n @keyframes slop-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n `}</style>\n <div className={className} style={style}>\n <div\n className=\"slop-wrapper relative overflow-hidden w-full h-full\"\n style={{\n aspectRatio: String(aspectRatio).replace(\":\", \"/\"),\n position: \"relative\",\n overflow: \"hidden\",\n width: \"100%\",\n height: \"100%\",\n }}\n >\n {/* Loading UI */}\n {loader ? (\n <div\n className={cn(\n \"absolute inset-0 z-10 flex items-center justify-center transition-opacity duration-300\",\n isLoading ? \"opacity-100\" : \"opacity-0 pointer-events-none\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n opacity: isLoading ? 1 : 0,\n pointerEvents: isLoading ? \"auto\" : \"none\",\n transition: \"opacity 300ms ease-in-out\",\n }}\n >\n {loader}\n </div>\n ) : (\n <>\n {/* Loading overlay */}\n <div\n className={cn(\n \"absolute inset-0 z-10 flex items-center justify-center bg-muted transition-opacity duration-300\",\n isLoading ? \"opacity-100\" : \"opacity-0 pointer-events-none\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"var(--muted, #f3f4f6)\",\n opacity: isLoading ? 1 : 0,\n pointerEvents: isLoading ? \"auto\" : \"none\",\n transition: \"opacity 300ms ease-in-out\",\n }}\n >\n <div\n className=\"flex flex-col items-center gap-2\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"0.5rem\",\n }}\n >\n <svg\n className=\"spinner size-6 text-muted-foreground\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n style={{\n width: \"24px\",\n height: \"24px\",\n color: \"var(--muted-foreground, #6b7280)\",\n animation: \"slop-spin 1s linear infinite\",\n }}\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n style={{ opacity: 0.25 }}\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n style={{ opacity: 0.75 }}\n />\n </svg>\n <span\n className=\"text-xs text-muted-foreground\"\n style={{\n fontSize: \"0.75rem\",\n color: \"var(--muted-foreground, #6b7280)\",\n }}\n >\n Loading...\n </span>\n </div>\n </div>\n\n {/* Shimmer effect underneath */}\n <div\n className={cn(\n \"shimmer-effect absolute inset-0 bg-gradient-to-r from-muted via-muted/50 to-muted\",\n isLoading ? \"opacity-100\" : \"opacity-0\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n background:\n \"linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)\",\n backgroundSize: \"200% 100%\",\n animation: \"slop-shimmer 2s ease-in-out infinite\",\n opacity: isLoading ? 1 : 0,\n transition: \"opacity 300ms\",\n }}\n />\n </>\n )}\n\n {/* Image */}\n <img\n key={src}\n src={src}\n alt={alt}\n {...props}\n onLoad={(e) => {\n setIsLoading(false);\n onLoad?.(e);\n }}\n onError={(e) => {\n setIsLoading(false);\n onError?.(e);\n }}\n className={cn(\n \"h-full w-full transition-opacity duration-500\",\n isLoading ? \"opacity-0\" : \"opacity-100\",\n imageClassName,\n )}\n style={{\n height: \"100%\",\n width: \"100%\",\n objectFit,\n transition: \"opacity 500ms\",\n opacity: isLoading ? 0 : 1,\n }}\n />\n </div>\n </div>\n </>\n );\n};\n","import React, { useMemo, useState, useRef, useEffect } from \"react\";\nimport { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nimport {\n buildVideoUrl,\n type SlopVideoOptions,\n type VideoAspectRatio,\n} from \"@slopmachine/core\";\n\n// Utility for Tailwind classes\nfunction cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport interface SlopVideoProps\n extends\n Omit<React.VideoHTMLAttributes<HTMLVideoElement>, \"src\">,\n Omit<SlopVideoOptions, \"aspectRatio\"> {\n /**\n * The aspect ratio of the generated video. Defaults to \"16:9\".\n */\n aspectRatio?: VideoAspectRatio;\n /**\n * Custom React node to display while the video is loading.\n * If not provided, a default spinner and shimmer effect will be shown.\n */\n loader?: React.ReactNode;\n}\n\n/**\n * Renders a video generated by Slop Machine.\n *\n * This component automatically constructs the correct URL for the Slop Machine API,\n * displays a loading skeleton or custom loader while fetching, and handles errors.\n *\n * @example\n * ```tsx\n * // Using a Bucket\n * <SlopVideo\n * bucketId=\"my-bucket\"\n * resultId=\"some-result\"\n * aspectRatio=\"16:9\"\n * className=\"rounded-lg\"\n * autoPlay\n * loop\n * muted\n * />\n *\n * // Using a Pipeline with runtime prompt\n * <SlopVideo\n * pipelineId=\"pipe_live_abc123\"\n * prompt=\"Drone shot of a cyberpunk city in rain\"\n * aspectRatio=\"16:9\"\n * metadata={{ campaign: \"spring_launch\" }}\n * />\n * ```\n *\n * @version 0.4.0\n */\nexport const SlopVideo: React.FC<SlopVideoProps> = ({\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n className,\n aspectRatio = \"16:9\",\n version,\n resultId,\n variables = {},\n duration,\n baseUrl,\n original,\n attachments,\n loader,\n autoPlay = true,\n loop = true,\n muted = true,\n playsInline = true,\n onLoadedData,\n onError,\n ...props\n}) => {\n // Construct API URL\n const rawSrc = useMemo(\n () =>\n buildVideoUrl({\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n aspectRatio,\n version,\n resultId,\n variables,\n duration,\n baseUrl,\n original,\n attachments,\n }),\n [\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n aspectRatio,\n version,\n resultId,\n variables,\n duration,\n baseUrl,\n original,\n attachments,\n ],\n );\n\n const [src, setSrc] = useState(rawSrc);\n\n useEffect(() => {\n const timer = setTimeout(() => {\n setSrc(rawSrc);\n }, 100);\n return () => clearTimeout(timer);\n }, [rawSrc]);\n\n const [isLoading, setIsLoading] = useState(true);\n const [currentSrc, setCurrentSrc] = useState(src);\n const videoRef = useRef<HTMLVideoElement>(null);\n\n if (src !== currentSrc) {\n setCurrentSrc(src);\n setIsLoading(true);\n }\n\n useEffect(() => {\n if (!src) return;\n\n fetch(src, { method: \"HEAD\" })\n .then(async (res) => {\n if (!res.ok) {\n let errorMessage = res.statusText;\n try {\n const errRes = await fetch(src);\n const errorText = await errRes.text();\n const errorData = JSON.parse(errorText);\n if (errorData.error) {\n errorMessage = errorData.error;\n }\n } catch (e) {\n // Failed to fetch or parse error details\n }\n console.error(\"SlopVideo error:\", res.status, errorMessage);\n setIsLoading(false);\n }\n })\n .catch((err) => {\n console.error(`Error fetching video from ${src}:`, err);\n setIsLoading(false);\n });\n }, [src]);\n\n return (\n <>\n <style>{`\n @keyframes slop-shimmer {\n 0% {\n background-position: 200% 0;\n }\n 100% {\n background-position: -200% 0;\n }\n }\n @keyframes slop-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n `}</style>\n <div className={className} style={props.style}>\n <div\n className=\"slop-wrapper relative overflow-hidden w-full h-full\"\n style={{\n aspectRatio: String(aspectRatio).replace(\":\", \"/\"),\n position: \"relative\",\n overflow: \"hidden\",\n width: \"100%\",\n height: \"100%\",\n }}\n >\n {/* Loading UI */}\n {loader ? (\n <div\n className={cn(\n \"absolute inset-0 z-10 flex items-center justify-center transition-opacity duration-300\",\n isLoading ? \"opacity-100\" : \"opacity-0 pointer-events-none\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n opacity: isLoading ? 1 : 0,\n pointerEvents: isLoading ? \"auto\" : \"none\",\n transition: \"opacity 300ms ease-in-out\",\n }}\n >\n {loader}\n </div>\n ) : (\n <>\n {/* Loading overlay */}\n <div\n className={cn(\n \"absolute inset-0 z-10 flex items-center justify-center bg-muted transition-opacity duration-300\",\n isLoading ? \"opacity-100\" : \"opacity-0 pointer-events-none\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"var(--muted, #f3f4f6)\",\n opacity: isLoading ? 1 : 0,\n pointerEvents: isLoading ? \"auto\" : \"none\",\n transition: \"opacity 300ms ease-in-out\",\n }}\n >\n <div\n className=\"flex flex-col items-center gap-2\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"0.5rem\",\n }}\n >\n <svg\n className=\"spinner size-6 text-muted-foreground\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n style={{\n width: \"24px\",\n height: \"24px\",\n color: \"var(--muted-foreground, #6b7280)\",\n animation: \"slop-spin 1s linear infinite\",\n }}\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n style={{ opacity: 0.25 }}\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n style={{ opacity: 0.75 }}\n />\n </svg>\n <span\n className=\"text-xs text-muted-foreground\"\n style={{\n fontSize: \"0.75rem\",\n color: \"var(--muted-foreground, #6b7280)\",\n }}\n >\n Loading...\n </span>\n </div>\n </div>\n\n {/* Shimmer effect underneath */}\n <div\n className={cn(\n \"shimmer-effect absolute inset-0 bg-gradient-to-r from-muted via-muted/50 to-muted\",\n isLoading ? \"opacity-100\" : \"opacity-0\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n background:\n \"linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)\",\n backgroundSize: \"200% 100%\",\n animation: \"slop-shimmer 2s ease-in-out infinite\",\n opacity: isLoading ? 1 : 0,\n transition: \"opacity 300ms\",\n }}\n />\n </>\n )}\n\n {/* Video */}\n <video\n key={src}\n ref={videoRef}\n src={src}\n autoPlay={autoPlay}\n loop={loop}\n muted={muted}\n playsInline={playsInline}\n {...props}\n onLoadedData={(e) => {\n setIsLoading(false);\n onLoadedData?.(e);\n }}\n onError={(e) => {\n setIsLoading(false);\n onError?.(e);\n }}\n className={cn(\n \"h-full w-full object-cover transition-opacity duration-500\",\n isLoading ? \"opacity-0\" : \"opacity-100\",\n )}\n style={{\n height: \"100%\",\n width: \"100%\",\n objectFit: \"cover\",\n transition: \"opacity 500ms\",\n opacity: isLoading ? 0 : 1,\n }}\n />\n </div>\n </div>\n </>\n );\n};\n","import React, { useEffect, useMemo, useState } from \"react\";\nimport { buildTextUrl, type SlopTextOptions } from \"@slopmachine/core\";\nimport { marked } from \"marked\";\n\nexport interface SlopTextProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, \"children\">,\n SlopTextOptions {\n /**\n * Optional loading component to show while the text is being generated\n */\n fallback?: React.ReactNode;\n /**\n * Optional error component to show if the text generation fails\n */\n errorFallback?: React.ReactNode;\n}\n\n/**\n * Renders text generated by Slop Machine.\n *\n * This component automatically constructs the correct URL for the Slop Machine API,\n * fetches the generated text, and displays it with optional loading and error states.\n *\n * @example\n * ```tsx\n * // Using a Bucket\n * <SlopText\n * bucketId=\"my-text-bucket\"\n * fallback={<div>Loading story...</div>}\n * errorFallback={<div>Failed to load story</div>}\n * className=\"text-lg text-gray-800\"\n * />\n *\n * // Using a Pipeline with runtime prompt\n * <SlopText\n * pipelineId=\"pipe_live_abc123\"\n * prompt=\"Write a whimsical haiku about quantum physics\"\n * metadata={{ userId: \"123\" }}\n * />\n * ```\n *\n * @version 0.4.0\n */\nexport const SlopText = React.forwardRef<HTMLDivElement, SlopTextProps>(\n (\n {\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n version,\n resultId,\n variables,\n baseUrl,\n attachments,\n fallback,\n errorFallback,\n ...props\n },\n ref,\n ) => {\n const [text, setText] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const rawUrl = useMemo(\n () =>\n buildTextUrl({\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n version,\n resultId,\n variables,\n baseUrl,\n attachments,\n }),\n [\n bucketId,\n pipelineId,\n siloId,\n prompt,\n JSON.stringify(metadata),\n version,\n resultId,\n JSON.stringify(variables),\n baseUrl,\n JSON.stringify(attachments),\n ],\n );\n\n useEffect(() => {\n let isMounted = true;\n\n const fetchText = async () => {\n try {\n setLoading(true);\n setError(null);\n\n // Fetch the URL to get the content, following redirects automatically\n const response = await fetch(rawUrl, { cache: \"no-store\" });\n if (!response.ok) {\n let errorMessage = response.statusText;\n try {\n const errorText = await response.text();\n const errorData = JSON.parse(errorText);\n if (errorData.error) {\n errorMessage = errorData.error;\n }\n } catch (e) {\n // Ignore JSON parse errors if the response isn't JSON\n }\n throw new Error(`Failed to fetch text: ${errorMessage}`);\n }\n const content = await response.text();\n if (isMounted) {\n setText(content);\n }\n } catch (err) {\n if (isMounted) {\n const finalError =\n err instanceof Error ? err : new Error(\"Failed to generate text\");\n console.error(finalError);\n setError(finalError);\n }\n } finally {\n if (isMounted) {\n setLoading(false);\n }\n }\n };\n\n fetchText();\n\n return () => {\n isMounted = false;\n };\n }, [rawUrl]);\n\n if (error && errorFallback) {\n return <>{errorFallback}</>;\n }\n\n if (loading) {\n if (fallback) {\n return <>{fallback}</>;\n }\n return (\n <div className={props.className} style={props.style}>\n <style>{`\n @keyframes slop-shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n }\n @keyframes slop-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n `}</style>\n <div\n className=\"slop-wrapper relative overflow-hidden w-full\"\n style={{\n position: \"relative\",\n overflow: \"hidden\",\n width: \"100%\",\n minHeight: \"100px\",\n }}\n >\n {/* Loading overlay */}\n <div\n className=\"absolute inset-0 z-10 flex items-center justify-center bg-muted transition-opacity duration-300\"\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"var(--muted, #f3f4f6)\",\n }}\n >\n <div\n className=\"flex flex-col items-center gap-2\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"0.5rem\",\n }}\n >\n <svg\n className=\"spinner size-6 text-muted-foreground\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n style={{\n width: \"24px\",\n height: \"24px\",\n color: \"var(--muted-foreground, #6b7280)\",\n animation: \"slop-spin 1s linear infinite\",\n }}\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n style={{ opacity: 0.25 }}\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n style={{ opacity: 0.75 }}\n />\n </svg>\n <span\n className=\"text-xs text-muted-foreground\"\n style={{\n fontSize: \"0.75rem\",\n color: \"var(--muted-foreground, #6b7280)\",\n }}\n >\n Loading...\n </span>\n </div>\n </div>\n\n {/* Shimmer effect underneath */}\n <div\n className=\"shimmer-effect absolute inset-0 bg-gradient-to-r from-muted via-muted/50 to-muted\"\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n background:\n \"linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)\",\n backgroundSize: \"200% 100%\",\n animation: \"slop-shimmer 2s ease-in-out infinite\",\n }}\n />\n </div>\n </div>\n );\n }\n\n return (\n <div\n ref={ref}\n {...props}\n dangerouslySetInnerHTML={{\n __html: text ? (marked.parse(text) as string) : \"\",\n }}\n />\n );\n },\n);\n\nSlopText.displayName = \"SlopText\";\n"],"mappings":"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","names":["React","import_react","import_clsx","import_tailwind_merge","import_core","import_jsx_runtime","cn","import_react","import_core","import_jsx_runtime","React","import_core"]}
package/dist/index.mjs CHANGED
@@ -19,7 +19,6 @@ var SlopImage = ({
19
19
  aspectRatio = "1:1",
20
20
  version,
21
21
  resultId,
22
- quality = "fast",
23
22
  variables = {},
24
23
  baseUrl,
25
24
  original,
@@ -44,7 +43,6 @@ var SlopImage = ({
44
43
  resultId,
45
44
  variables,
46
45
  baseUrl,
47
- quality,
48
46
  original,
49
47
  attachments
50
48
  }),
@@ -59,7 +57,6 @@ var SlopImage = ({
59
57
  resultId,
60
58
  variables,
61
59
  baseUrl,
62
- quality,
63
60
  original,
64
61
  attachments
65
62
  ]
@@ -320,7 +317,6 @@ var SlopVideo = ({
320
317
  aspectRatio = "16:9",
321
318
  version,
322
319
  resultId,
323
- quality = "fast",
324
320
  variables = {},
325
321
  duration,
326
322
  baseUrl,
@@ -348,7 +344,6 @@ var SlopVideo = ({
348
344
  variables,
349
345
  duration,
350
346
  baseUrl,
351
- quality,
352
347
  original,
353
348
  attachments
354
349
  }),
@@ -364,7 +359,6 @@ var SlopVideo = ({
364
359
  variables,
365
360
  duration,
366
361
  baseUrl,
367
- quality,
368
362
  original,
369
363
  attachments
370
364
  ]
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/SlopImage.tsx","../src/components/SlopVideo.tsx","../src/components/SlopText.tsx","../src/index.ts"],"sourcesContent":["import React, { useMemo, useState } from \"react\";\nimport { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nimport {\n buildImageUrl,\n type SlopImageOptions,\n type ImageAspectRatio,\n} from \"@slopmachine/core\";\n\n// Utility for Tailwind classes\nfunction cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport interface SlopImageProps\n extends\n Omit<React.ImgHTMLAttributes<HTMLImageElement>, \"src\" | \"alt\">,\n Omit<SlopImageOptions, \"aspectRatio\"> {\n /**\n * The aspect ratio of the generated image. Defaults to \"1:1\".\n */\n aspectRatio?: ImageAspectRatio;\n /**\n * Custom React node to display while the image is loading.\n * If not provided, a default spinner and shimmer effect will be shown.\n */\n loader?: React.ReactNode;\n /**\n * How the image should be resized to fit its container. Defaults to \"cover\".\n */\n objectFit?: React.CSSProperties[\"objectFit\"];\n /**\n * Additional CSS classes to apply directly to the `<img />` element.\n */\n imageClassName?: string;\n}\n\n/**\n * Renders an image generated by Slop Machine.\n *\n * This component automatically constructs the correct URL for the Slop Machine API,\n * displays a loading skeleton or custom loader while fetching, and handles errors.\n *\n * @example\n * ```tsx\n * // Using a Bucket\n * <SlopImage\n * bucketId=\"my-bucket\"\n * resultId=\"some-result\"\n * aspectRatio=\"16:9\"\n * className=\"rounded-lg\"\n * objectFit=\"cover\"\n * />\n *\n * // Using a Pipeline with runtime prompt\n * <SlopImage\n * pipelineId=\"pipe_live_abc123\"\n * prompt=\"1960s retro robot eating pizza on Mars\"\n * aspectRatio=\"16:9\"\n * metadata={{ userId: \"123\" }}\n * />\n * ```\n *\n * @version 0.3.0\n */\nexport const SlopImage: React.FC<SlopImageProps> = ({\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n className,\n aspectRatio = \"1:1\",\n version,\n resultId,\n quality = \"fast\",\n variables = {},\n baseUrl,\n original,\n attachments,\n loader,\n objectFit = \"cover\",\n imageClassName,\n style,\n onLoad,\n onError,\n ...props\n}) => {\n // Construct API URL\n const rawSrc = useMemo(\n () =>\n buildImageUrl({\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n aspectRatio,\n version,\n resultId,\n variables,\n baseUrl,\n quality,\n original,\n attachments,\n }),\n [\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n aspectRatio,\n version,\n resultId,\n variables,\n baseUrl,\n quality,\n original,\n attachments,\n ],\n );\n\n const [src, setSrc] = useState(rawSrc);\n\n React.useEffect(() => {\n const timer = setTimeout(() => {\n setSrc(rawSrc);\n }, 100);\n return () => clearTimeout(timer);\n }, [rawSrc]);\n\n const alt = \"Image produced by Slop Machine (slopmachine.dev)\";\n\n const [isLoading, setIsLoading] = useState(true);\n const [currentSrc, setCurrentSrc] = useState(src);\n\n if (src !== currentSrc) {\n setCurrentSrc(src);\n setIsLoading(true);\n }\n\n React.useEffect(() => {\n if (!src) return;\n\n fetch(src, { method: \"HEAD\" })\n .then(async (res) => {\n if (!res.ok) {\n let errorMessage = res.statusText;\n try {\n const errRes = await fetch(src);\n const errorText = await errRes.text();\n const errorData = JSON.parse(errorText);\n if (errorData.error) {\n errorMessage = errorData.error;\n }\n } catch (e) {\n // Failed to fetch or parse error details\n }\n console.error(\"SlopImage error:\", res.status, errorMessage);\n setIsLoading(false);\n }\n })\n .catch((err) => {\n console.error(`Error fetching image from ${src}:`, err);\n setIsLoading(false);\n });\n }, [src]);\n\n return (\n <>\n <style>{`\n @keyframes slop-shimmer {\n 0% {\n background-position: 200% 0;\n }\n 100% {\n background-position: -200% 0;\n }\n }\n @keyframes slop-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n `}</style>\n <div className={className} style={style}>\n <div\n className=\"slop-wrapper relative overflow-hidden w-full h-full\"\n style={{\n aspectRatio: String(aspectRatio).replace(\":\", \"/\"),\n position: \"relative\",\n overflow: \"hidden\",\n width: \"100%\",\n height: \"100%\",\n }}\n >\n {/* Loading UI */}\n {loader ? (\n <div\n className={cn(\n \"absolute inset-0 z-10 flex items-center justify-center transition-opacity duration-300\",\n isLoading ? \"opacity-100\" : \"opacity-0 pointer-events-none\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n opacity: isLoading ? 1 : 0,\n pointerEvents: isLoading ? \"auto\" : \"none\",\n transition: \"opacity 300ms ease-in-out\",\n }}\n >\n {loader}\n </div>\n ) : (\n <>\n {/* Loading overlay */}\n <div\n className={cn(\n \"absolute inset-0 z-10 flex items-center justify-center bg-muted transition-opacity duration-300\",\n isLoading ? \"opacity-100\" : \"opacity-0 pointer-events-none\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"var(--muted, #f3f4f6)\",\n opacity: isLoading ? 1 : 0,\n pointerEvents: isLoading ? \"auto\" : \"none\",\n transition: \"opacity 300ms ease-in-out\",\n }}\n >\n <div\n className=\"flex flex-col items-center gap-2\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"0.5rem\",\n }}\n >\n <svg\n className=\"spinner size-6 text-muted-foreground\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n style={{\n width: \"24px\",\n height: \"24px\",\n color: \"var(--muted-foreground, #6b7280)\",\n animation: \"slop-spin 1s linear infinite\",\n }}\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n style={{ opacity: 0.25 }}\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n style={{ opacity: 0.75 }}\n />\n </svg>\n <span\n className=\"text-xs text-muted-foreground\"\n style={{\n fontSize: \"0.75rem\",\n color: \"var(--muted-foreground, #6b7280)\",\n }}\n >\n Loading...\n </span>\n </div>\n </div>\n\n {/* Shimmer effect underneath */}\n <div\n className={cn(\n \"shimmer-effect absolute inset-0 bg-gradient-to-r from-muted via-muted/50 to-muted\",\n isLoading ? \"opacity-100\" : \"opacity-0\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n background:\n \"linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)\",\n backgroundSize: \"200% 100%\",\n animation: \"slop-shimmer 2s ease-in-out infinite\",\n opacity: isLoading ? 1 : 0,\n transition: \"opacity 300ms\",\n }}\n />\n </>\n )}\n\n {/* Image */}\n <img\n key={src}\n src={src}\n alt={alt}\n {...props}\n onLoad={(e) => {\n setIsLoading(false);\n onLoad?.(e);\n }}\n onError={(e) => {\n setIsLoading(false);\n onError?.(e);\n }}\n className={cn(\n \"h-full w-full transition-opacity duration-500\",\n isLoading ? \"opacity-0\" : \"opacity-100\",\n imageClassName,\n )}\n style={{\n height: \"100%\",\n width: \"100%\",\n objectFit,\n transition: \"opacity 500ms\",\n opacity: isLoading ? 0 : 1,\n }}\n />\n </div>\n </div>\n </>\n );\n};\n","import React, { useMemo, useState, useRef, useEffect } from \"react\";\nimport { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nimport {\n buildVideoUrl,\n type SlopVideoOptions,\n type VideoAspectRatio,\n} from \"@slopmachine/core\";\n\n// Utility for Tailwind classes\nfunction cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport interface SlopVideoProps\n extends\n Omit<React.VideoHTMLAttributes<HTMLVideoElement>, \"src\">,\n Omit<SlopVideoOptions, \"aspectRatio\"> {\n /**\n * The aspect ratio of the generated video. Defaults to \"16:9\".\n */\n aspectRatio?: VideoAspectRatio;\n /**\n * Custom React node to display while the video is loading.\n * If not provided, a default spinner and shimmer effect will be shown.\n */\n loader?: React.ReactNode;\n}\n\n/**\n * Renders a video generated by Slop Machine.\n *\n * This component automatically constructs the correct URL for the Slop Machine API,\n * displays a loading skeleton or custom loader while fetching, and handles errors.\n *\n * @example\n * ```tsx\n * // Using a Bucket\n * <SlopVideo\n * bucketId=\"my-bucket\"\n * resultId=\"some-result\"\n * aspectRatio=\"16:9\"\n * className=\"rounded-lg\"\n * autoPlay\n * loop\n * muted\n * />\n *\n * // Using a Pipeline with runtime prompt\n * <SlopVideo\n * pipelineId=\"pipe_live_abc123\"\n * prompt=\"Drone shot of a cyberpunk city in rain\"\n * aspectRatio=\"16:9\"\n * metadata={{ campaign: \"spring_launch\" }}\n * />\n * ```\n *\n * @version 0.3.0\n */\nexport const SlopVideo: React.FC<SlopVideoProps> = ({\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n className,\n aspectRatio = \"16:9\",\n version,\n resultId,\n quality = \"fast\",\n variables = {},\n duration,\n baseUrl,\n original,\n attachments,\n loader,\n autoPlay = true,\n loop = true,\n muted = true,\n playsInline = true,\n onLoadedData,\n onError,\n ...props\n}) => {\n // Construct API URL\n const rawSrc = useMemo(\n () =>\n buildVideoUrl({\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n aspectRatio,\n version,\n resultId,\n variables,\n duration,\n baseUrl,\n quality,\n original,\n attachments,\n }),\n [\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n aspectRatio,\n version,\n resultId,\n variables,\n duration,\n baseUrl,\n quality,\n original,\n attachments,\n ],\n );\n\n const [src, setSrc] = useState(rawSrc);\n\n useEffect(() => {\n const timer = setTimeout(() => {\n setSrc(rawSrc);\n }, 100);\n return () => clearTimeout(timer);\n }, [rawSrc]);\n\n const [isLoading, setIsLoading] = useState(true);\n const [currentSrc, setCurrentSrc] = useState(src);\n const videoRef = useRef<HTMLVideoElement>(null);\n\n if (src !== currentSrc) {\n setCurrentSrc(src);\n setIsLoading(true);\n }\n\n useEffect(() => {\n if (!src) return;\n\n fetch(src, { method: \"HEAD\" })\n .then(async (res) => {\n if (!res.ok) {\n let errorMessage = res.statusText;\n try {\n const errRes = await fetch(src);\n const errorText = await errRes.text();\n const errorData = JSON.parse(errorText);\n if (errorData.error) {\n errorMessage = errorData.error;\n }\n } catch (e) {\n // Failed to fetch or parse error details\n }\n console.error(\"SlopVideo error:\", res.status, errorMessage);\n setIsLoading(false);\n }\n })\n .catch((err) => {\n console.error(`Error fetching video from ${src}:`, err);\n setIsLoading(false);\n });\n }, [src]);\n\n return (\n <>\n <style>{`\n @keyframes slop-shimmer {\n 0% {\n background-position: 200% 0;\n }\n 100% {\n background-position: -200% 0;\n }\n }\n @keyframes slop-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n `}</style>\n <div className={className} style={props.style}>\n <div\n className=\"slop-wrapper relative overflow-hidden w-full h-full\"\n style={{\n aspectRatio: String(aspectRatio).replace(\":\", \"/\"),\n position: \"relative\",\n overflow: \"hidden\",\n width: \"100%\",\n height: \"100%\",\n }}\n >\n {/* Loading UI */}\n {loader ? (\n <div\n className={cn(\n \"absolute inset-0 z-10 flex items-center justify-center transition-opacity duration-300\",\n isLoading ? \"opacity-100\" : \"opacity-0 pointer-events-none\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n opacity: isLoading ? 1 : 0,\n pointerEvents: isLoading ? \"auto\" : \"none\",\n transition: \"opacity 300ms ease-in-out\",\n }}\n >\n {loader}\n </div>\n ) : (\n <>\n {/* Loading overlay */}\n <div\n className={cn(\n \"absolute inset-0 z-10 flex items-center justify-center bg-muted transition-opacity duration-300\",\n isLoading ? \"opacity-100\" : \"opacity-0 pointer-events-none\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"var(--muted, #f3f4f6)\",\n opacity: isLoading ? 1 : 0,\n pointerEvents: isLoading ? \"auto\" : \"none\",\n transition: \"opacity 300ms ease-in-out\",\n }}\n >\n <div\n className=\"flex flex-col items-center gap-2\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"0.5rem\",\n }}\n >\n <svg\n className=\"spinner size-6 text-muted-foreground\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n style={{\n width: \"24px\",\n height: \"24px\",\n color: \"var(--muted-foreground, #6b7280)\",\n animation: \"slop-spin 1s linear infinite\",\n }}\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n style={{ opacity: 0.25 }}\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n style={{ opacity: 0.75 }}\n />\n </svg>\n <span\n className=\"text-xs text-muted-foreground\"\n style={{\n fontSize: \"0.75rem\",\n color: \"var(--muted-foreground, #6b7280)\",\n }}\n >\n Loading...\n </span>\n </div>\n </div>\n\n {/* Shimmer effect underneath */}\n <div\n className={cn(\n \"shimmer-effect absolute inset-0 bg-gradient-to-r from-muted via-muted/50 to-muted\",\n isLoading ? \"opacity-100\" : \"opacity-0\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n background:\n \"linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)\",\n backgroundSize: \"200% 100%\",\n animation: \"slop-shimmer 2s ease-in-out infinite\",\n opacity: isLoading ? 1 : 0,\n transition: \"opacity 300ms\",\n }}\n />\n </>\n )}\n\n {/* Video */}\n <video\n key={src}\n ref={videoRef}\n src={src}\n autoPlay={autoPlay}\n loop={loop}\n muted={muted}\n playsInline={playsInline}\n {...props}\n onLoadedData={(e) => {\n setIsLoading(false);\n onLoadedData?.(e);\n }}\n onError={(e) => {\n setIsLoading(false);\n onError?.(e);\n }}\n className={cn(\n \"h-full w-full object-cover transition-opacity duration-500\",\n isLoading ? \"opacity-0\" : \"opacity-100\",\n )}\n style={{\n height: \"100%\",\n width: \"100%\",\n objectFit: \"cover\",\n transition: \"opacity 500ms\",\n opacity: isLoading ? 0 : 1,\n }}\n />\n </div>\n </div>\n </>\n );\n};\n","import React, { useEffect, useMemo, useState } from \"react\";\nimport { buildTextUrl, type SlopTextOptions } from \"@slopmachine/core\";\nimport { marked } from \"marked\";\n\nexport interface SlopTextProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, \"children\">,\n SlopTextOptions {\n /**\n * Optional loading component to show while the text is being generated\n */\n fallback?: React.ReactNode;\n /**\n * Optional error component to show if the text generation fails\n */\n errorFallback?: React.ReactNode;\n}\n\n/**\n * Renders text generated by Slop Machine.\n *\n * This component automatically constructs the correct URL for the Slop Machine API,\n * fetches the generated text, and displays it with optional loading and error states.\n *\n * @example\n * ```tsx\n * // Using a Bucket\n * <SlopText\n * bucketId=\"my-text-bucket\"\n * fallback={<div>Loading story...</div>}\n * errorFallback={<div>Failed to load story</div>}\n * className=\"text-lg text-gray-800\"\n * />\n *\n * // Using a Pipeline with runtime prompt\n * <SlopText\n * pipelineId=\"pipe_live_abc123\"\n * prompt=\"Write a whimsical haiku about quantum physics\"\n * metadata={{ userId: \"123\" }}\n * />\n * ```\n *\n * @version 0.3.0\n */\nexport const SlopText = React.forwardRef<HTMLDivElement, SlopTextProps>(\n (\n {\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n version,\n resultId,\n variables,\n baseUrl,\n attachments,\n fallback,\n errorFallback,\n ...props\n },\n ref,\n ) => {\n const [text, setText] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const rawUrl = useMemo(\n () =>\n buildTextUrl({\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n version,\n resultId,\n variables,\n baseUrl,\n attachments,\n }),\n [\n bucketId,\n pipelineId,\n siloId,\n prompt,\n JSON.stringify(metadata),\n version,\n resultId,\n JSON.stringify(variables),\n baseUrl,\n JSON.stringify(attachments),\n ],\n );\n\n useEffect(() => {\n let isMounted = true;\n\n const fetchText = async () => {\n try {\n setLoading(true);\n setError(null);\n\n // Fetch the URL to get the content, following redirects automatically\n const response = await fetch(rawUrl, { cache: \"no-store\" });\n if (!response.ok) {\n let errorMessage = response.statusText;\n try {\n const errorText = await response.text();\n const errorData = JSON.parse(errorText);\n if (errorData.error) {\n errorMessage = errorData.error;\n }\n } catch (e) {\n // Ignore JSON parse errors if the response isn't JSON\n }\n throw new Error(`Failed to fetch text: ${errorMessage}`);\n }\n const content = await response.text();\n if (isMounted) {\n setText(content);\n }\n } catch (err) {\n if (isMounted) {\n const finalError =\n err instanceof Error ? err : new Error(\"Failed to generate text\");\n console.error(finalError);\n setError(finalError);\n }\n } finally {\n if (isMounted) {\n setLoading(false);\n }\n }\n };\n\n fetchText();\n\n return () => {\n isMounted = false;\n };\n }, [rawUrl]);\n\n if (error && errorFallback) {\n return <>{errorFallback}</>;\n }\n\n if (loading) {\n if (fallback) {\n return <>{fallback}</>;\n }\n return (\n <div className={props.className} style={props.style}>\n <style>{`\n @keyframes slop-shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n }\n @keyframes slop-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n `}</style>\n <div\n className=\"slop-wrapper relative overflow-hidden w-full\"\n style={{\n position: \"relative\",\n overflow: \"hidden\",\n width: \"100%\",\n minHeight: \"100px\",\n }}\n >\n {/* Loading overlay */}\n <div\n className=\"absolute inset-0 z-10 flex items-center justify-center bg-muted transition-opacity duration-300\"\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"var(--muted, #f3f4f6)\",\n }}\n >\n <div\n className=\"flex flex-col items-center gap-2\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"0.5rem\",\n }}\n >\n <svg\n className=\"spinner size-6 text-muted-foreground\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n style={{\n width: \"24px\",\n height: \"24px\",\n color: \"var(--muted-foreground, #6b7280)\",\n animation: \"slop-spin 1s linear infinite\",\n }}\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n style={{ opacity: 0.25 }}\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n style={{ opacity: 0.75 }}\n />\n </svg>\n <span\n className=\"text-xs text-muted-foreground\"\n style={{\n fontSize: \"0.75rem\",\n color: \"var(--muted-foreground, #6b7280)\",\n }}\n >\n Loading...\n </span>\n </div>\n </div>\n\n {/* Shimmer effect underneath */}\n <div\n className=\"shimmer-effect absolute inset-0 bg-gradient-to-r from-muted via-muted/50 to-muted\"\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n background:\n \"linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)\",\n backgroundSize: \"200% 100%\",\n animation: \"slop-shimmer 2s ease-in-out infinite\",\n }}\n />\n </div>\n </div>\n );\n }\n\n return (\n <div\n ref={ref}\n {...props}\n dangerouslySetInnerHTML={{\n __html: text ? (marked.parse(text) as string) : \"\",\n }}\n />\n );\n },\n);\n\nSlopText.displayName = \"SlopText\";\n","export { SlopImage, type SlopImageProps } from \"./components/SlopImage\";\nexport { SlopVideo, type SlopVideoProps } from \"./components/SlopVideo\";\nexport { SlopText, type SlopTextProps } from \"./components/SlopText\";\n\nexport type {\n ImageAspectRatio,\n VideoAspectRatio,\n SlopImageOptions,\n SlopVideoOptions,\n} from \"@slopmachine/core\";\n\nexport { preloadImage } from \"@slopmachine/core\";\n"],"mappings":"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","names":["useMemo","useState","clsx","twMerge","Fragment","jsx","jsxs","cn","React","useEffect","useMemo","useState","Fragment","jsx","jsxs"]}
1
+ {"version":3,"sources":["../src/components/SlopImage.tsx","../src/components/SlopVideo.tsx","../src/components/SlopText.tsx","../src/index.ts"],"sourcesContent":["import React, { useMemo, useState } from \"react\";\nimport { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nimport {\n buildImageUrl,\n type SlopImageOptions,\n type ImageAspectRatio,\n} from \"@slopmachine/core\";\n\n// Utility for Tailwind classes\nfunction cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport interface SlopImageProps\n extends\n Omit<React.ImgHTMLAttributes<HTMLImageElement>, \"src\" | \"alt\">,\n Omit<SlopImageOptions, \"aspectRatio\"> {\n /**\n * The aspect ratio of the generated image. Defaults to \"1:1\".\n */\n aspectRatio?: ImageAspectRatio;\n /**\n * Custom React node to display while the image is loading.\n * If not provided, a default spinner and shimmer effect will be shown.\n */\n loader?: React.ReactNode;\n /**\n * How the image should be resized to fit its container. Defaults to \"cover\".\n */\n objectFit?: React.CSSProperties[\"objectFit\"];\n /**\n * Additional CSS classes to apply directly to the `<img />` element.\n */\n imageClassName?: string;\n}\n\n/**\n * Renders an image generated by Slop Machine.\n *\n * This component automatically constructs the correct URL for the Slop Machine API,\n * displays a loading skeleton or custom loader while fetching, and handles errors.\n *\n * @example\n * ```tsx\n * // Using a Bucket\n * <SlopImage\n * bucketId=\"my-bucket\"\n * resultId=\"some-result\"\n * aspectRatio=\"16:9\"\n * className=\"rounded-lg\"\n * objectFit=\"cover\"\n * />\n *\n * // Using a Pipeline with runtime prompt\n * <SlopImage\n * pipelineId=\"pipe_live_abc123\"\n * prompt=\"1960s retro robot eating pizza on Mars\"\n * aspectRatio=\"16:9\"\n * metadata={{ userId: \"123\" }}\n * />\n * ```\n *\n * @version 0.4.0\n */\nexport const SlopImage: React.FC<SlopImageProps> = ({\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n className,\n aspectRatio = \"1:1\",\n version,\n resultId,\n variables = {},\n baseUrl,\n original,\n attachments,\n loader,\n objectFit = \"cover\",\n imageClassName,\n style,\n onLoad,\n onError,\n ...props\n}) => {\n // Construct API URL\n const rawSrc = useMemo(\n () =>\n buildImageUrl({\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n aspectRatio,\n version,\n resultId,\n variables,\n baseUrl,\n original,\n attachments,\n }),\n [\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n aspectRatio,\n version,\n resultId,\n variables,\n baseUrl,\n original,\n attachments,\n ],\n );\n\n const [src, setSrc] = useState(rawSrc);\n\n React.useEffect(() => {\n const timer = setTimeout(() => {\n setSrc(rawSrc);\n }, 100);\n return () => clearTimeout(timer);\n }, [rawSrc]);\n\n const alt = \"Image produced by Slop Machine (slopmachine.dev)\";\n\n const [isLoading, setIsLoading] = useState(true);\n const [currentSrc, setCurrentSrc] = useState(src);\n\n if (src !== currentSrc) {\n setCurrentSrc(src);\n setIsLoading(true);\n }\n\n React.useEffect(() => {\n if (!src) return;\n\n fetch(src, { method: \"HEAD\" })\n .then(async (res) => {\n if (!res.ok) {\n let errorMessage = res.statusText;\n try {\n const errRes = await fetch(src);\n const errorText = await errRes.text();\n const errorData = JSON.parse(errorText);\n if (errorData.error) {\n errorMessage = errorData.error;\n }\n } catch (e) {\n // Failed to fetch or parse error details\n }\n console.error(\"SlopImage error:\", res.status, errorMessage);\n setIsLoading(false);\n }\n })\n .catch((err) => {\n console.error(`Error fetching image from ${src}:`, err);\n setIsLoading(false);\n });\n }, [src]);\n\n return (\n <>\n <style>{`\n @keyframes slop-shimmer {\n 0% {\n background-position: 200% 0;\n }\n 100% {\n background-position: -200% 0;\n }\n }\n @keyframes slop-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n `}</style>\n <div className={className} style={style}>\n <div\n className=\"slop-wrapper relative overflow-hidden w-full h-full\"\n style={{\n aspectRatio: String(aspectRatio).replace(\":\", \"/\"),\n position: \"relative\",\n overflow: \"hidden\",\n width: \"100%\",\n height: \"100%\",\n }}\n >\n {/* Loading UI */}\n {loader ? (\n <div\n className={cn(\n \"absolute inset-0 z-10 flex items-center justify-center transition-opacity duration-300\",\n isLoading ? \"opacity-100\" : \"opacity-0 pointer-events-none\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n opacity: isLoading ? 1 : 0,\n pointerEvents: isLoading ? \"auto\" : \"none\",\n transition: \"opacity 300ms ease-in-out\",\n }}\n >\n {loader}\n </div>\n ) : (\n <>\n {/* Loading overlay */}\n <div\n className={cn(\n \"absolute inset-0 z-10 flex items-center justify-center bg-muted transition-opacity duration-300\",\n isLoading ? \"opacity-100\" : \"opacity-0 pointer-events-none\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"var(--muted, #f3f4f6)\",\n opacity: isLoading ? 1 : 0,\n pointerEvents: isLoading ? \"auto\" : \"none\",\n transition: \"opacity 300ms ease-in-out\",\n }}\n >\n <div\n className=\"flex flex-col items-center gap-2\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"0.5rem\",\n }}\n >\n <svg\n className=\"spinner size-6 text-muted-foreground\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n style={{\n width: \"24px\",\n height: \"24px\",\n color: \"var(--muted-foreground, #6b7280)\",\n animation: \"slop-spin 1s linear infinite\",\n }}\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n style={{ opacity: 0.25 }}\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n style={{ opacity: 0.75 }}\n />\n </svg>\n <span\n className=\"text-xs text-muted-foreground\"\n style={{\n fontSize: \"0.75rem\",\n color: \"var(--muted-foreground, #6b7280)\",\n }}\n >\n Loading...\n </span>\n </div>\n </div>\n\n {/* Shimmer effect underneath */}\n <div\n className={cn(\n \"shimmer-effect absolute inset-0 bg-gradient-to-r from-muted via-muted/50 to-muted\",\n isLoading ? \"opacity-100\" : \"opacity-0\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n background:\n \"linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)\",\n backgroundSize: \"200% 100%\",\n animation: \"slop-shimmer 2s ease-in-out infinite\",\n opacity: isLoading ? 1 : 0,\n transition: \"opacity 300ms\",\n }}\n />\n </>\n )}\n\n {/* Image */}\n <img\n key={src}\n src={src}\n alt={alt}\n {...props}\n onLoad={(e) => {\n setIsLoading(false);\n onLoad?.(e);\n }}\n onError={(e) => {\n setIsLoading(false);\n onError?.(e);\n }}\n className={cn(\n \"h-full w-full transition-opacity duration-500\",\n isLoading ? \"opacity-0\" : \"opacity-100\",\n imageClassName,\n )}\n style={{\n height: \"100%\",\n width: \"100%\",\n objectFit,\n transition: \"opacity 500ms\",\n opacity: isLoading ? 0 : 1,\n }}\n />\n </div>\n </div>\n </>\n );\n};\n","import React, { useMemo, useState, useRef, useEffect } from \"react\";\nimport { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nimport {\n buildVideoUrl,\n type SlopVideoOptions,\n type VideoAspectRatio,\n} from \"@slopmachine/core\";\n\n// Utility for Tailwind classes\nfunction cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport interface SlopVideoProps\n extends\n Omit<React.VideoHTMLAttributes<HTMLVideoElement>, \"src\">,\n Omit<SlopVideoOptions, \"aspectRatio\"> {\n /**\n * The aspect ratio of the generated video. Defaults to \"16:9\".\n */\n aspectRatio?: VideoAspectRatio;\n /**\n * Custom React node to display while the video is loading.\n * If not provided, a default spinner and shimmer effect will be shown.\n */\n loader?: React.ReactNode;\n}\n\n/**\n * Renders a video generated by Slop Machine.\n *\n * This component automatically constructs the correct URL for the Slop Machine API,\n * displays a loading skeleton or custom loader while fetching, and handles errors.\n *\n * @example\n * ```tsx\n * // Using a Bucket\n * <SlopVideo\n * bucketId=\"my-bucket\"\n * resultId=\"some-result\"\n * aspectRatio=\"16:9\"\n * className=\"rounded-lg\"\n * autoPlay\n * loop\n * muted\n * />\n *\n * // Using a Pipeline with runtime prompt\n * <SlopVideo\n * pipelineId=\"pipe_live_abc123\"\n * prompt=\"Drone shot of a cyberpunk city in rain\"\n * aspectRatio=\"16:9\"\n * metadata={{ campaign: \"spring_launch\" }}\n * />\n * ```\n *\n * @version 0.4.0\n */\nexport const SlopVideo: React.FC<SlopVideoProps> = ({\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n className,\n aspectRatio = \"16:9\",\n version,\n resultId,\n variables = {},\n duration,\n baseUrl,\n original,\n attachments,\n loader,\n autoPlay = true,\n loop = true,\n muted = true,\n playsInline = true,\n onLoadedData,\n onError,\n ...props\n}) => {\n // Construct API URL\n const rawSrc = useMemo(\n () =>\n buildVideoUrl({\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n aspectRatio,\n version,\n resultId,\n variables,\n duration,\n baseUrl,\n original,\n attachments,\n }),\n [\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n aspectRatio,\n version,\n resultId,\n variables,\n duration,\n baseUrl,\n original,\n attachments,\n ],\n );\n\n const [src, setSrc] = useState(rawSrc);\n\n useEffect(() => {\n const timer = setTimeout(() => {\n setSrc(rawSrc);\n }, 100);\n return () => clearTimeout(timer);\n }, [rawSrc]);\n\n const [isLoading, setIsLoading] = useState(true);\n const [currentSrc, setCurrentSrc] = useState(src);\n const videoRef = useRef<HTMLVideoElement>(null);\n\n if (src !== currentSrc) {\n setCurrentSrc(src);\n setIsLoading(true);\n }\n\n useEffect(() => {\n if (!src) return;\n\n fetch(src, { method: \"HEAD\" })\n .then(async (res) => {\n if (!res.ok) {\n let errorMessage = res.statusText;\n try {\n const errRes = await fetch(src);\n const errorText = await errRes.text();\n const errorData = JSON.parse(errorText);\n if (errorData.error) {\n errorMessage = errorData.error;\n }\n } catch (e) {\n // Failed to fetch or parse error details\n }\n console.error(\"SlopVideo error:\", res.status, errorMessage);\n setIsLoading(false);\n }\n })\n .catch((err) => {\n console.error(`Error fetching video from ${src}:`, err);\n setIsLoading(false);\n });\n }, [src]);\n\n return (\n <>\n <style>{`\n @keyframes slop-shimmer {\n 0% {\n background-position: 200% 0;\n }\n 100% {\n background-position: -200% 0;\n }\n }\n @keyframes slop-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n `}</style>\n <div className={className} style={props.style}>\n <div\n className=\"slop-wrapper relative overflow-hidden w-full h-full\"\n style={{\n aspectRatio: String(aspectRatio).replace(\":\", \"/\"),\n position: \"relative\",\n overflow: \"hidden\",\n width: \"100%\",\n height: \"100%\",\n }}\n >\n {/* Loading UI */}\n {loader ? (\n <div\n className={cn(\n \"absolute inset-0 z-10 flex items-center justify-center transition-opacity duration-300\",\n isLoading ? \"opacity-100\" : \"opacity-0 pointer-events-none\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n opacity: isLoading ? 1 : 0,\n pointerEvents: isLoading ? \"auto\" : \"none\",\n transition: \"opacity 300ms ease-in-out\",\n }}\n >\n {loader}\n </div>\n ) : (\n <>\n {/* Loading overlay */}\n <div\n className={cn(\n \"absolute inset-0 z-10 flex items-center justify-center bg-muted transition-opacity duration-300\",\n isLoading ? \"opacity-100\" : \"opacity-0 pointer-events-none\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"var(--muted, #f3f4f6)\",\n opacity: isLoading ? 1 : 0,\n pointerEvents: isLoading ? \"auto\" : \"none\",\n transition: \"opacity 300ms ease-in-out\",\n }}\n >\n <div\n className=\"flex flex-col items-center gap-2\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"0.5rem\",\n }}\n >\n <svg\n className=\"spinner size-6 text-muted-foreground\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n style={{\n width: \"24px\",\n height: \"24px\",\n color: \"var(--muted-foreground, #6b7280)\",\n animation: \"slop-spin 1s linear infinite\",\n }}\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n style={{ opacity: 0.25 }}\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n style={{ opacity: 0.75 }}\n />\n </svg>\n <span\n className=\"text-xs text-muted-foreground\"\n style={{\n fontSize: \"0.75rem\",\n color: \"var(--muted-foreground, #6b7280)\",\n }}\n >\n Loading...\n </span>\n </div>\n </div>\n\n {/* Shimmer effect underneath */}\n <div\n className={cn(\n \"shimmer-effect absolute inset-0 bg-gradient-to-r from-muted via-muted/50 to-muted\",\n isLoading ? \"opacity-100\" : \"opacity-0\",\n )}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n background:\n \"linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)\",\n backgroundSize: \"200% 100%\",\n animation: \"slop-shimmer 2s ease-in-out infinite\",\n opacity: isLoading ? 1 : 0,\n transition: \"opacity 300ms\",\n }}\n />\n </>\n )}\n\n {/* Video */}\n <video\n key={src}\n ref={videoRef}\n src={src}\n autoPlay={autoPlay}\n loop={loop}\n muted={muted}\n playsInline={playsInline}\n {...props}\n onLoadedData={(e) => {\n setIsLoading(false);\n onLoadedData?.(e);\n }}\n onError={(e) => {\n setIsLoading(false);\n onError?.(e);\n }}\n className={cn(\n \"h-full w-full object-cover transition-opacity duration-500\",\n isLoading ? \"opacity-0\" : \"opacity-100\",\n )}\n style={{\n height: \"100%\",\n width: \"100%\",\n objectFit: \"cover\",\n transition: \"opacity 500ms\",\n opacity: isLoading ? 0 : 1,\n }}\n />\n </div>\n </div>\n </>\n );\n};\n","import React, { useEffect, useMemo, useState } from \"react\";\nimport { buildTextUrl, type SlopTextOptions } from \"@slopmachine/core\";\nimport { marked } from \"marked\";\n\nexport interface SlopTextProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, \"children\">,\n SlopTextOptions {\n /**\n * Optional loading component to show while the text is being generated\n */\n fallback?: React.ReactNode;\n /**\n * Optional error component to show if the text generation fails\n */\n errorFallback?: React.ReactNode;\n}\n\n/**\n * Renders text generated by Slop Machine.\n *\n * This component automatically constructs the correct URL for the Slop Machine API,\n * fetches the generated text, and displays it with optional loading and error states.\n *\n * @example\n * ```tsx\n * // Using a Bucket\n * <SlopText\n * bucketId=\"my-text-bucket\"\n * fallback={<div>Loading story...</div>}\n * errorFallback={<div>Failed to load story</div>}\n * className=\"text-lg text-gray-800\"\n * />\n *\n * // Using a Pipeline with runtime prompt\n * <SlopText\n * pipelineId=\"pipe_live_abc123\"\n * prompt=\"Write a whimsical haiku about quantum physics\"\n * metadata={{ userId: \"123\" }}\n * />\n * ```\n *\n * @version 0.4.0\n */\nexport const SlopText = React.forwardRef<HTMLDivElement, SlopTextProps>(\n (\n {\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n version,\n resultId,\n variables,\n baseUrl,\n attachments,\n fallback,\n errorFallback,\n ...props\n },\n ref,\n ) => {\n const [text, setText] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const rawUrl = useMemo(\n () =>\n buildTextUrl({\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n version,\n resultId,\n variables,\n baseUrl,\n attachments,\n }),\n [\n bucketId,\n pipelineId,\n siloId,\n prompt,\n JSON.stringify(metadata),\n version,\n resultId,\n JSON.stringify(variables),\n baseUrl,\n JSON.stringify(attachments),\n ],\n );\n\n useEffect(() => {\n let isMounted = true;\n\n const fetchText = async () => {\n try {\n setLoading(true);\n setError(null);\n\n // Fetch the URL to get the content, following redirects automatically\n const response = await fetch(rawUrl, { cache: \"no-store\" });\n if (!response.ok) {\n let errorMessage = response.statusText;\n try {\n const errorText = await response.text();\n const errorData = JSON.parse(errorText);\n if (errorData.error) {\n errorMessage = errorData.error;\n }\n } catch (e) {\n // Ignore JSON parse errors if the response isn't JSON\n }\n throw new Error(`Failed to fetch text: ${errorMessage}`);\n }\n const content = await response.text();\n if (isMounted) {\n setText(content);\n }\n } catch (err) {\n if (isMounted) {\n const finalError =\n err instanceof Error ? err : new Error(\"Failed to generate text\");\n console.error(finalError);\n setError(finalError);\n }\n } finally {\n if (isMounted) {\n setLoading(false);\n }\n }\n };\n\n fetchText();\n\n return () => {\n isMounted = false;\n };\n }, [rawUrl]);\n\n if (error && errorFallback) {\n return <>{errorFallback}</>;\n }\n\n if (loading) {\n if (fallback) {\n return <>{fallback}</>;\n }\n return (\n <div className={props.className} style={props.style}>\n <style>{`\n @keyframes slop-shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n }\n @keyframes slop-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n `}</style>\n <div\n className=\"slop-wrapper relative overflow-hidden w-full\"\n style={{\n position: \"relative\",\n overflow: \"hidden\",\n width: \"100%\",\n minHeight: \"100px\",\n }}\n >\n {/* Loading overlay */}\n <div\n className=\"absolute inset-0 z-10 flex items-center justify-center bg-muted transition-opacity duration-300\"\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"var(--muted, #f3f4f6)\",\n }}\n >\n <div\n className=\"flex flex-col items-center gap-2\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"0.5rem\",\n }}\n >\n <svg\n className=\"spinner size-6 text-muted-foreground\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n style={{\n width: \"24px\",\n height: \"24px\",\n color: \"var(--muted-foreground, #6b7280)\",\n animation: \"slop-spin 1s linear infinite\",\n }}\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n style={{ opacity: 0.25 }}\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n style={{ opacity: 0.75 }}\n />\n </svg>\n <span\n className=\"text-xs text-muted-foreground\"\n style={{\n fontSize: \"0.75rem\",\n color: \"var(--muted-foreground, #6b7280)\",\n }}\n >\n Loading...\n </span>\n </div>\n </div>\n\n {/* Shimmer effect underneath */}\n <div\n className=\"shimmer-effect absolute inset-0 bg-gradient-to-r from-muted via-muted/50 to-muted\"\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n background:\n \"linear-gradient(90deg, var(--muted, #f3f4f6) 0%, var(--muted-foreground, #e5e7eb) 50%, var(--muted, #f3f4f6) 100%)\",\n backgroundSize: \"200% 100%\",\n animation: \"slop-shimmer 2s ease-in-out infinite\",\n }}\n />\n </div>\n </div>\n );\n }\n\n return (\n <div\n ref={ref}\n {...props}\n dangerouslySetInnerHTML={{\n __html: text ? (marked.parse(text) as string) : \"\",\n }}\n />\n );\n },\n);\n\nSlopText.displayName = \"SlopText\";\n","export { SlopImage, type SlopImageProps } from \"./components/SlopImage\";\nexport { SlopVideo, type SlopVideoProps } from \"./components/SlopVideo\";\nexport { SlopText, type SlopTextProps } from \"./components/SlopText\";\n\nexport type {\n ImageAspectRatio,\n VideoAspectRatio,\n SlopImageOptions,\n SlopVideoOptions,\n} from \"@slopmachine/core\";\n\nexport { preloadImage } from \"@slopmachine/core\";\n"],"mappings":"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","names":["useMemo","useState","clsx","twMerge","Fragment","jsx","jsxs","cn","React","useEffect","useMemo","useState","Fragment","jsx","jsxs"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slopmachine/react",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "llms": "https://docs.slopmachine.dev/llms.txt",
5
5
  "llmsFull": "https://docs.slopmachine.dev/llms-full.txt",
6
6
  "description": "The official React SDK for Slop Machine",
@@ -47,7 +47,7 @@
47
47
  "@radix-ui/react-label": "^2.1.8",
48
48
  "@radix-ui/react-select": "^2.2.6",
49
49
  "@radix-ui/react-slot": "^1.2.4",
50
- "@slopmachine/core": "^0.3.0",
50
+ "@slopmachine/core": "^0.4.0",
51
51
  "@tailwindcss/postcss": "^4.1.18",
52
52
  "@tailwindcss/vite": "^4.1.18",
53
53
  "@types/marked": "^5.0.2",
@@ -62,7 +62,7 @@ export interface SlopImageProps
62
62
  * />
63
63
  * ```
64
64
  *
65
- * @version 0.3.0
65
+ * @version 0.4.0
66
66
  */
67
67
  export const SlopImage: React.FC<SlopImageProps> = ({
68
68
  bucketId,
@@ -74,7 +74,6 @@ export const SlopImage: React.FC<SlopImageProps> = ({
74
74
  aspectRatio = "1:1",
75
75
  version,
76
76
  resultId,
77
- quality = "fast",
78
77
  variables = {},
79
78
  baseUrl,
80
79
  original,
@@ -101,7 +100,6 @@ export const SlopImage: React.FC<SlopImageProps> = ({
101
100
  resultId,
102
101
  variables,
103
102
  baseUrl,
104
- quality,
105
103
  original,
106
104
  attachments,
107
105
  }),
@@ -116,7 +114,6 @@ export const SlopImage: React.FC<SlopImageProps> = ({
116
114
  resultId,
117
115
  variables,
118
116
  baseUrl,
119
- quality,
120
117
  original,
121
118
  attachments,
122
119
  ],
@@ -40,7 +40,7 @@ export interface SlopTextProps
40
40
  * />
41
41
  * ```
42
42
  *
43
- * @version 0.3.0
43
+ * @version 0.4.0
44
44
  */
45
45
  export const SlopText = React.forwardRef<HTMLDivElement, SlopTextProps>(
46
46
  (
@@ -56,7 +56,7 @@ export interface SlopVideoProps
56
56
  * />
57
57
  * ```
58
58
  *
59
- * @version 0.3.0
59
+ * @version 0.4.0
60
60
  */
61
61
  export const SlopVideo: React.FC<SlopVideoProps> = ({
62
62
  bucketId,
@@ -68,7 +68,6 @@ export const SlopVideo: React.FC<SlopVideoProps> = ({
68
68
  aspectRatio = "16:9",
69
69
  version,
70
70
  resultId,
71
- quality = "fast",
72
71
  variables = {},
73
72
  duration,
74
73
  baseUrl,
@@ -98,7 +97,6 @@ export const SlopVideo: React.FC<SlopVideoProps> = ({
98
97
  variables,
99
98
  duration,
100
99
  baseUrl,
101
- quality,
102
100
  original,
103
101
  attachments,
104
102
  }),
@@ -114,7 +112,6 @@ export const SlopVideo: React.FC<SlopVideoProps> = ({
114
112
  variables,
115
113
  duration,
116
114
  baseUrl,
117
- quality,
118
115
  original,
119
116
  attachments,
120
117
  ],