@slopmachine/react 0.6.0 → 0.8.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/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  "use strict";
2
3
  var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
@@ -31,6 +32,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
32
  var index_exports = {};
32
33
  __export(index_exports, {
33
34
  SlopImage: () => SlopImage,
35
+ SlopMachineError: () => import_core4.SlopMachineError,
34
36
  SlopText: () => SlopText,
35
37
  SlopVideo: () => SlopVideo,
36
38
  preloadImage: () => import_core4.preloadImage,
@@ -41,11 +43,86 @@ __export(index_exports, {
41
43
  module.exports = __toCommonJS(index_exports);
42
44
 
43
45
  // src/components/SlopImage.tsx
44
- var import_react = __toESM(require("react"));
46
+ var import_react = require("react");
45
47
  var import_clsx = require("clsx");
46
48
  var import_tailwind_merge = require("tailwind-merge");
47
49
  var import_core = require("@slopmachine/core");
50
+
51
+ // src/components/ErrorOverlay.tsx
48
52
  var import_jsx_runtime = require("react/jsx-runtime");
53
+ var overlayStyle = {
54
+ position: "absolute",
55
+ top: 0,
56
+ left: 0,
57
+ right: 0,
58
+ bottom: 0,
59
+ zIndex: 10,
60
+ display: "flex",
61
+ alignItems: "center",
62
+ justifyContent: "center"
63
+ };
64
+ var ErrorOverlay = ({
65
+ error,
66
+ errorFallback,
67
+ label
68
+ }) => {
69
+ if (errorFallback !== void 0) {
70
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
71
+ "div",
72
+ {
73
+ className: "absolute inset-0 z-10 flex items-center justify-center",
74
+ style: overlayStyle,
75
+ children: typeof errorFallback === "function" ? errorFallback(error) : errorFallback
76
+ }
77
+ );
78
+ }
79
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
80
+ "div",
81
+ {
82
+ className: "absolute inset-0 z-10 flex items-center justify-center bg-muted",
83
+ style: { ...overlayStyle, backgroundColor: "var(--muted, #f3f4f6)" },
84
+ title: error.message,
85
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
86
+ "div",
87
+ {
88
+ className: "flex flex-col items-center gap-2 text-muted-foreground",
89
+ style: {
90
+ display: "flex",
91
+ flexDirection: "column",
92
+ alignItems: "center",
93
+ gap: "0.5rem",
94
+ color: "var(--muted-foreground, #6b7280)"
95
+ },
96
+ children: [
97
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
98
+ "svg",
99
+ {
100
+ xmlns: "http://www.w3.org/2000/svg",
101
+ viewBox: "0 0 24 24",
102
+ fill: "none",
103
+ stroke: "currentColor",
104
+ strokeWidth: "2",
105
+ strokeLinecap: "round",
106
+ strokeLinejoin: "round",
107
+ "aria-hidden": "true",
108
+ style: { width: "24px", height: "24px" },
109
+ children: [
110
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
111
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
112
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
113
+ ]
114
+ }
115
+ ),
116
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-xs", style: { fontSize: "0.75rem" }, children: label })
117
+ ]
118
+ }
119
+ )
120
+ }
121
+ );
122
+ };
123
+
124
+ // src/components/SlopImage.tsx
125
+ var import_jsx_runtime2 = require("react/jsx-runtime");
49
126
  function cn(...inputs) {
50
127
  return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
51
128
  }
@@ -65,6 +142,8 @@ var SlopImage = ({
65
142
  original,
66
143
  attachments,
67
144
  loader,
145
+ errorFallback,
146
+ onGenerationError,
68
147
  objectFit = "cover",
69
148
  imageClassName,
70
149
  style,
@@ -105,7 +184,7 @@ var SlopImage = ({
105
184
  ]
106
185
  );
107
186
  const [src, setSrc] = (0, import_react.useState)(rawSrc);
108
- import_react.default.useEffect(() => {
187
+ (0, import_react.useEffect)(() => {
109
188
  const timer = setTimeout(() => {
110
189
  setSrc(rawSrc);
111
190
  }, 100);
@@ -113,35 +192,33 @@ var SlopImage = ({
113
192
  }, [rawSrc]);
114
193
  const alt = "Image produced by Slop Machine (slopmachine.dev)";
115
194
  const [isLoading, setIsLoading] = (0, import_react.useState)(true);
195
+ const [error, setError] = (0, import_react.useState)(null);
116
196
  const [currentSrc, setCurrentSrc] = (0, import_react.useState)(src);
117
197
  if (src !== currentSrc) {
118
198
  setCurrentSrc(src);
119
199
  setIsLoading(true);
200
+ setError(null);
120
201
  }
121
- import_react.default.useEffect(() => {
122
- if (!src) return;
123
- fetch(src, { method: "HEAD" }).then(async (res) => {
124
- if (!res.ok) {
125
- let errorMessage = res.statusText;
126
- try {
127
- const errRes = await fetch(src);
128
- const errorText = await errRes.text();
129
- const errorData = JSON.parse(errorText);
130
- if (errorData.error) {
131
- errorMessage = errorData.error;
132
- }
133
- } catch (e) {
134
- }
135
- console.error("SlopImage error:", res.status, errorMessage);
136
- setIsLoading(false);
137
- }
138
- }).catch((err) => {
139
- console.error(`Error fetching image from ${src}:`, err);
202
+ const onGenerationErrorRef = (0, import_react.useRef)(onGenerationError);
203
+ (0, import_react.useEffect)(() => {
204
+ onGenerationErrorRef.current = onGenerationError;
205
+ });
206
+ const monitor = (0, import_react.useMemo)(
207
+ () => (0, import_core.createRenderUrlMonitor)((err) => {
208
+ console.error("SlopImage error:", err.status ?? "", err.message);
140
209
  setIsLoading(false);
141
- });
142
- }, [src]);
143
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
144
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: `
210
+ setError(err);
211
+ onGenerationErrorRef.current?.(err);
212
+ }),
213
+ []
214
+ );
215
+ (0, import_react.useEffect)(() => {
216
+ if (!src) return;
217
+ monitor.watch(src);
218
+ return () => monitor.stop();
219
+ }, [src, monitor]);
220
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
221
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { children: `
145
222
  @keyframes slop-shimmer {
146
223
  0% {
147
224
  background-position: 200% 0;
@@ -159,7 +236,7 @@ var SlopImage = ({
159
236
  }
160
237
  }
161
238
  ` }),
162
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className, style, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
239
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className, style, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
163
240
  "div",
164
241
  {
165
242
  className: "slop-wrapper relative overflow-hidden w-full h-full",
@@ -171,7 +248,7 @@ var SlopImage = ({
171
248
  height: "100%"
172
249
  },
173
250
  children: [
174
- loader ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
251
+ loader ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
175
252
  "div",
176
253
  {
177
254
  className: cn(
@@ -194,8 +271,8 @@ var SlopImage = ({
194
271
  },
195
272
  children: loader
196
273
  }
197
- ) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
198
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
274
+ ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
275
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
199
276
  "div",
200
277
  {
201
278
  className: cn(
@@ -217,7 +294,7 @@ var SlopImage = ({
217
294
  pointerEvents: isLoading ? "auto" : "none",
218
295
  transition: "opacity 300ms ease-in-out"
219
296
  },
220
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
297
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
221
298
  "div",
222
299
  {
223
300
  className: "flex flex-col items-center gap-2",
@@ -228,7 +305,7 @@ var SlopImage = ({
228
305
  gap: "0.5rem"
229
306
  },
230
307
  children: [
231
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
308
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
232
309
  "svg",
233
310
  {
234
311
  className: "spinner size-6 text-muted-foreground",
@@ -242,7 +319,7 @@ var SlopImage = ({
242
319
  animation: "slop-spin 1s linear infinite"
243
320
  },
244
321
  children: [
245
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
322
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
246
323
  "circle",
247
324
  {
248
325
  className: "opacity-25",
@@ -254,7 +331,7 @@ var SlopImage = ({
254
331
  style: { opacity: 0.25 }
255
332
  }
256
333
  ),
257
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
334
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
258
335
  "path",
259
336
  {
260
337
  className: "opacity-75",
@@ -266,7 +343,7 @@ var SlopImage = ({
266
343
  ]
267
344
  }
268
345
  ),
269
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
346
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
270
347
  "span",
271
348
  {
272
349
  className: "text-xs text-muted-foreground",
@@ -282,7 +359,7 @@ var SlopImage = ({
282
359
  )
283
360
  }
284
361
  ),
285
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
362
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
286
363
  "div",
287
364
  {
288
365
  className: cn(
@@ -304,7 +381,15 @@ var SlopImage = ({
304
381
  }
305
382
  )
306
383
  ] }),
307
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
384
+ error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
385
+ ErrorOverlay,
386
+ {
387
+ error,
388
+ errorFallback,
389
+ label: "Failed to load image"
390
+ }
391
+ ),
392
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
308
393
  "img",
309
394
  {
310
395
  src,
@@ -315,12 +400,13 @@ var SlopImage = ({
315
400
  onLoad?.(e);
316
401
  },
317
402
  onError: (e) => {
318
- setIsLoading(false);
403
+ monitor.mediaFailed(src, "Failed to load image");
319
404
  onError?.(e);
320
405
  },
406
+ "aria-hidden": error ? true : props["aria-hidden"],
321
407
  className: cn(
322
408
  "h-full w-full transition-opacity duration-500",
323
- isLoading ? "opacity-0" : "opacity-100",
409
+ isLoading || error ? "opacity-0" : "opacity-100",
324
410
  imageClassName
325
411
  ),
326
412
  style: {
@@ -328,7 +414,7 @@ var SlopImage = ({
328
414
  width: "100%",
329
415
  objectFit,
330
416
  transition: "opacity 500ms",
331
- opacity: isLoading ? 0 : 1
417
+ opacity: isLoading || error ? 0 : 1
332
418
  }
333
419
  },
334
420
  src
@@ -344,7 +430,7 @@ var import_react2 = require("react");
344
430
  var import_clsx2 = require("clsx");
345
431
  var import_tailwind_merge2 = require("tailwind-merge");
346
432
  var import_core2 = require("@slopmachine/core");
347
- var import_jsx_runtime2 = require("react/jsx-runtime");
433
+ var import_jsx_runtime3 = require("react/jsx-runtime");
348
434
  function cn2(...inputs) {
349
435
  return (0, import_tailwind_merge2.twMerge)((0, import_clsx2.clsx)(inputs));
350
436
  }
@@ -364,6 +450,8 @@ var SlopVideo = ({
364
450
  original,
365
451
  attachments,
366
452
  loader,
453
+ errorFallback,
454
+ onGenerationError,
367
455
  autoPlay = true,
368
456
  loop = true,
369
457
  muted = true,
@@ -412,36 +500,34 @@ var SlopVideo = ({
412
500
  return () => clearTimeout(timer);
413
501
  }, [rawSrc]);
414
502
  const [isLoading, setIsLoading] = (0, import_react2.useState)(true);
503
+ const [error, setError] = (0, import_react2.useState)(null);
415
504
  const [currentSrc, setCurrentSrc] = (0, import_react2.useState)(src);
416
505
  const videoRef = (0, import_react2.useRef)(null);
417
506
  if (src !== currentSrc) {
418
507
  setCurrentSrc(src);
419
508
  setIsLoading(true);
509
+ setError(null);
420
510
  }
511
+ const onGenerationErrorRef = (0, import_react2.useRef)(onGenerationError);
421
512
  (0, import_react2.useEffect)(() => {
422
- if (!src) return;
423
- fetch(src, { method: "HEAD" }).then(async (res) => {
424
- if (!res.ok) {
425
- let errorMessage = res.statusText;
426
- try {
427
- const errRes = await fetch(src);
428
- const errorText = await errRes.text();
429
- const errorData = JSON.parse(errorText);
430
- if (errorData.error) {
431
- errorMessage = errorData.error;
432
- }
433
- } catch (e) {
434
- }
435
- console.error("SlopVideo error:", res.status, errorMessage);
436
- setIsLoading(false);
437
- }
438
- }).catch((err) => {
439
- console.error(`Error fetching video from ${src}:`, err);
513
+ onGenerationErrorRef.current = onGenerationError;
514
+ });
515
+ const monitor = (0, import_react2.useMemo)(
516
+ () => (0, import_core2.createRenderUrlMonitor)((err) => {
517
+ console.error("SlopVideo error:", err.status ?? "", err.message);
440
518
  setIsLoading(false);
441
- });
442
- }, [src]);
443
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
444
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { children: `
519
+ setError(err);
520
+ onGenerationErrorRef.current?.(err);
521
+ }),
522
+ []
523
+ );
524
+ (0, import_react2.useEffect)(() => {
525
+ if (!src) return;
526
+ monitor.watch(src);
527
+ return () => monitor.stop();
528
+ }, [src, monitor]);
529
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
530
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("style", { children: `
445
531
  @keyframes slop-shimmer {
446
532
  0% {
447
533
  background-position: 200% 0;
@@ -459,7 +545,7 @@ var SlopVideo = ({
459
545
  }
460
546
  }
461
547
  ` }),
462
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className, style: props.style, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
548
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className, style: props.style, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
463
549
  "div",
464
550
  {
465
551
  className: "slop-wrapper relative overflow-hidden w-full h-full",
@@ -471,7 +557,7 @@ var SlopVideo = ({
471
557
  height: "100%"
472
558
  },
473
559
  children: [
474
- loader ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
560
+ loader ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
475
561
  "div",
476
562
  {
477
563
  className: cn2(
@@ -494,8 +580,8 @@ var SlopVideo = ({
494
580
  },
495
581
  children: loader
496
582
  }
497
- ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
498
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
583
+ ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
584
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
499
585
  "div",
500
586
  {
501
587
  className: cn2(
@@ -517,7 +603,7 @@ var SlopVideo = ({
517
603
  pointerEvents: isLoading ? "auto" : "none",
518
604
  transition: "opacity 300ms ease-in-out"
519
605
  },
520
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
606
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
521
607
  "div",
522
608
  {
523
609
  className: "flex flex-col items-center gap-2",
@@ -528,7 +614,7 @@ var SlopVideo = ({
528
614
  gap: "0.5rem"
529
615
  },
530
616
  children: [
531
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
617
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
532
618
  "svg",
533
619
  {
534
620
  className: "spinner size-6 text-muted-foreground",
@@ -542,7 +628,7 @@ var SlopVideo = ({
542
628
  animation: "slop-spin 1s linear infinite"
543
629
  },
544
630
  children: [
545
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
631
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
546
632
  "circle",
547
633
  {
548
634
  className: "opacity-25",
@@ -554,7 +640,7 @@ var SlopVideo = ({
554
640
  style: { opacity: 0.25 }
555
641
  }
556
642
  ),
557
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
643
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
558
644
  "path",
559
645
  {
560
646
  className: "opacity-75",
@@ -566,7 +652,7 @@ var SlopVideo = ({
566
652
  ]
567
653
  }
568
654
  ),
569
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
655
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
570
656
  "span",
571
657
  {
572
658
  className: "text-xs text-muted-foreground",
@@ -582,7 +668,7 @@ var SlopVideo = ({
582
668
  )
583
669
  }
584
670
  ),
585
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
671
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
586
672
  "div",
587
673
  {
588
674
  className: cn2(
@@ -604,7 +690,15 @@ var SlopVideo = ({
604
690
  }
605
691
  )
606
692
  ] }),
607
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
693
+ error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
694
+ ErrorOverlay,
695
+ {
696
+ error,
697
+ errorFallback,
698
+ label: "Failed to load video"
699
+ }
700
+ ),
701
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
608
702
  "video",
609
703
  {
610
704
  ref: videoRef,
@@ -619,19 +713,20 @@ var SlopVideo = ({
619
713
  onLoadedData?.(e);
620
714
  },
621
715
  onError: (e) => {
622
- setIsLoading(false);
716
+ monitor.mediaFailed(src, "Failed to load video");
623
717
  onError?.(e);
624
718
  },
719
+ "aria-hidden": error ? true : props["aria-hidden"],
625
720
  className: cn2(
626
721
  "h-full w-full object-cover transition-opacity duration-500",
627
- isLoading ? "opacity-0" : "opacity-100"
722
+ isLoading || error ? "opacity-0" : "opacity-100"
628
723
  ),
629
724
  style: {
630
725
  height: "100%",
631
726
  width: "100%",
632
727
  objectFit: "cover",
633
728
  transition: "opacity 500ms",
634
- opacity: isLoading ? 0 : 1
729
+ opacity: isLoading || error ? 0 : 1
635
730
  }
636
731
  },
637
732
  src
@@ -645,7 +740,7 @@ var SlopVideo = ({
645
740
  // src/components/SlopText.tsx
646
741
  var import_react3 = __toESM(require("react"));
647
742
  var import_core3 = require("@slopmachine/core");
648
- var import_jsx_runtime3 = require("react/jsx-runtime");
743
+ var import_jsx_runtime4 = require("react/jsx-runtime");
649
744
  var SlopText = import_react3.default.forwardRef(
650
745
  ({
651
746
  bucketId,
@@ -735,14 +830,14 @@ var SlopText = import_react3.default.forwardRef(
735
830
  };
736
831
  }, [rawUrl]);
737
832
  if (error && errorFallback) {
738
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children: errorFallback });
833
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: errorFallback });
739
834
  }
740
835
  if (loading) {
741
836
  if (fallback) {
742
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children: fallback });
837
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: fallback });
743
838
  }
744
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: props.className, style: props.style, children: [
745
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("style", { children: `
839
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: props.className, style: props.style, children: [
840
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("style", { children: `
746
841
  @keyframes slop-shimmer {
747
842
  0% { background-position: 200% 0; }
748
843
  100% { background-position: -200% 0; }
@@ -752,7 +847,7 @@ var SlopText = import_react3.default.forwardRef(
752
847
  to { transform: rotate(360deg); }
753
848
  }
754
849
  ` }),
755
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
850
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
756
851
  "div",
757
852
  {
758
853
  className: "slop-wrapper relative overflow-hidden w-full",
@@ -763,7 +858,7 @@ var SlopText = import_react3.default.forwardRef(
763
858
  minHeight: "100px"
764
859
  },
765
860
  children: [
766
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
861
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
767
862
  "div",
768
863
  {
769
864
  className: "absolute inset-0 z-10 flex items-center justify-center bg-muted transition-opacity duration-300",
@@ -779,7 +874,7 @@ var SlopText = import_react3.default.forwardRef(
779
874
  justifyContent: "center",
780
875
  backgroundColor: "var(--muted, #f3f4f6)"
781
876
  },
782
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
877
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
783
878
  "div",
784
879
  {
785
880
  className: "flex flex-col items-center gap-2",
@@ -790,7 +885,7 @@ var SlopText = import_react3.default.forwardRef(
790
885
  gap: "0.5rem"
791
886
  },
792
887
  children: [
793
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
888
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
794
889
  "svg",
795
890
  {
796
891
  className: "spinner size-6 text-muted-foreground",
@@ -804,7 +899,7 @@ var SlopText = import_react3.default.forwardRef(
804
899
  animation: "slop-spin 1s linear infinite"
805
900
  },
806
901
  children: [
807
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
902
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
808
903
  "circle",
809
904
  {
810
905
  className: "opacity-25",
@@ -816,7 +911,7 @@ var SlopText = import_react3.default.forwardRef(
816
911
  style: { opacity: 0.25 }
817
912
  }
818
913
  ),
819
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
914
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
820
915
  "path",
821
916
  {
822
917
  className: "opacity-75",
@@ -828,7 +923,7 @@ var SlopText = import_react3.default.forwardRef(
828
923
  ]
829
924
  }
830
925
  ),
831
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
926
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
832
927
  "span",
833
928
  {
834
929
  className: "text-xs text-muted-foreground",
@@ -844,7 +939,7 @@ var SlopText = import_react3.default.forwardRef(
844
939
  )
845
940
  }
846
941
  ),
847
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
942
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
848
943
  "div",
849
944
  {
850
945
  className: "shimmer-effect absolute inset-0 bg-gradient-to-r from-muted via-muted/50 to-muted",
@@ -865,7 +960,7 @@ var SlopText = import_react3.default.forwardRef(
865
960
  )
866
961
  ] });
867
962
  }
868
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
963
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
869
964
  "div",
870
965
  {
871
966
  ref,
@@ -884,6 +979,7 @@ var import_core4 = require("@slopmachine/core");
884
979
  // Annotate the CommonJS export names for ESM import in node:
885
980
  0 && (module.exports = {
886
981
  SlopImage,
982
+ SlopMachineError,
887
983
  SlopText,
888
984
  SlopVideo,
889
985
  preloadImage,