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