pxengine 0.1.77 → 0.1.78

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.cjs CHANGED
@@ -38998,7 +38998,6 @@ var ShareIcon = () => /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("svg", { w
38998
38998
  /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })
38999
38999
  ] });
39000
39000
  var CheckIcon = () => /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("polyline", { points: "20 6 9 17 4 12" }) });
39001
- var Skel = ({ className, style }) => /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: cn("animate-pulse rounded-md bg-zinc-800/60", className), style });
39002
39001
  var FORMATS = [
39003
39002
  {
39004
39003
  key: "pdf_url",
@@ -39168,6 +39167,23 @@ var FullscreenModal = ({ url, title, slideCount, onClose }) => {
39168
39167
  ) })
39169
39168
  ] });
39170
39169
  };
39170
+ var PROCESSING_STAGES = [
39171
+ { minProgress: 0, message: "Initializing..." },
39172
+ { minProgress: 12, message: "Analyzing request..." },
39173
+ { minProgress: 25, message: "Generating content..." },
39174
+ { minProgress: 45, message: "Building slides..." },
39175
+ { minProgress: 65, message: "Applying design..." },
39176
+ { minProgress: 80, message: "Rendering outputs..." },
39177
+ { minProgress: 92, message: "Finalizing..." }
39178
+ ];
39179
+ function getStageMessage(progress) {
39180
+ for (let i = PROCESSING_STAGES.length - 1; i >= 0; i--) {
39181
+ if (progress >= PROCESSING_STAGES[i].minProgress) {
39182
+ return PROCESSING_STAGES[i].message;
39183
+ }
39184
+ }
39185
+ return PROCESSING_STAGES[0].message;
39186
+ }
39171
39187
  var PresentationJobCard = ({
39172
39188
  job_id: _job_id,
39173
39189
  title: initialTitle,
@@ -39176,8 +39192,11 @@ var PresentationJobCard = ({
39176
39192
  formats: initialFormats = {},
39177
39193
  error: initialError,
39178
39194
  pollUrl,
39195
+ authToken,
39179
39196
  shareUrl,
39180
- className
39197
+ className,
39198
+ onComplete,
39199
+ onFailed
39181
39200
  }) => {
39182
39201
  const [status, setStatus] = (0, import_react75.useState)(initialStatus);
39183
39202
  const [title, setTitle] = (0, import_react75.useState)(initialTitle);
@@ -39191,9 +39210,40 @@ var PresentationJobCard = ({
39191
39210
  const [previewScale, setPreviewScale] = (0, import_react75.useState)(1);
39192
39211
  const [iframeReady, setIframeReady] = (0, import_react75.useState)(false);
39193
39212
  const [pendingSlide, setPendingSlide] = (0, import_react75.useState)(null);
39213
+ const [progress, setProgress] = (0, import_react75.useState)(0);
39214
+ const startTimeRef = (0, import_react75.useRef)(Date.now());
39194
39215
  const intervalRef = (0, import_react75.useRef)(null);
39216
+ const progressIntervalRef = (0, import_react75.useRef)(null);
39195
39217
  const previewRef = (0, import_react75.useRef)(null);
39196
39218
  const iframeRef = (0, import_react75.useRef)(null);
39219
+ (0, import_react75.useEffect)(() => {
39220
+ const isLoading = status === "pending" || status === "running";
39221
+ if (!isLoading) {
39222
+ if (progressIntervalRef.current) {
39223
+ clearInterval(progressIntervalRef.current);
39224
+ progressIntervalRef.current = null;
39225
+ }
39226
+ if (status === "complete") setProgress(100);
39227
+ return;
39228
+ }
39229
+ startTimeRef.current = Date.now();
39230
+ progressIntervalRef.current = setInterval(() => {
39231
+ const elapsed = (Date.now() - startTimeRef.current) / 1e3;
39232
+ const estimated = Math.min(90, 90 * (1 - Math.exp(-elapsed / 60)));
39233
+ setProgress((prev) => Math.max(prev, Math.round(estimated)));
39234
+ }, 500);
39235
+ return () => {
39236
+ if (progressIntervalRef.current) {
39237
+ clearInterval(progressIntervalRef.current);
39238
+ progressIntervalRef.current = null;
39239
+ }
39240
+ };
39241
+ }, [status]);
39242
+ (0, import_react75.useEffect)(() => {
39243
+ if (status === "running") {
39244
+ setProgress((prev) => Math.max(prev, 15));
39245
+ }
39246
+ }, [status]);
39197
39247
  const updateScale = (0, import_react75.useCallback)(() => {
39198
39248
  if (previewRef.current) setPreviewScale(previewRef.current.offsetWidth / 1280);
39199
39249
  }, []);
@@ -39238,21 +39288,48 @@ var PresentationJobCard = ({
39238
39288
  setPendingSlide(target);
39239
39289
  };
39240
39290
  const isTerminal = status === "complete" || status === "failed";
39291
+ const onCompleteRef = (0, import_react75.useRef)(onComplete);
39292
+ const onFailedRef = (0, import_react75.useRef)(onFailed);
39293
+ const hasNotifiedRef = (0, import_react75.useRef)(false);
39294
+ onCompleteRef.current = onComplete;
39295
+ onFailedRef.current = onFailed;
39241
39296
  (0, import_react75.useEffect)(() => {
39242
39297
  if (isTerminal || !pollUrl) return;
39243
39298
  const poll = async () => {
39244
39299
  try {
39245
- const res = await fetch(pollUrl);
39300
+ const headers = {};
39301
+ if (authToken) {
39302
+ headers["Authorization"] = `Bearer ${authToken}`;
39303
+ }
39304
+ const res = await fetch(pollUrl, { headers });
39246
39305
  if (!res.ok) return;
39247
39306
  const data = await res.json();
39248
39307
  const newStatus = data.status;
39249
39308
  setStatus(newStatus);
39250
39309
  if (newStatus === "complete" && data.output) {
39251
- if (data.output.title) setTitle(data.output.title);
39252
- if (data.output.slide_count) setSlideCount(data.output.slide_count);
39253
- if (data.output.formats) setFormats(data.output.formats);
39310
+ const newTitle = data.output.title || initialTitle;
39311
+ const newSlideCount = data.output.slide_count || 0;
39312
+ const newFormats = data.output.formats || {};
39313
+ setTitle(newTitle);
39314
+ setSlideCount(newSlideCount);
39315
+ setFormats(newFormats);
39316
+ if (!hasNotifiedRef.current && onCompleteRef.current) {
39317
+ hasNotifiedRef.current = true;
39318
+ onCompleteRef.current({
39319
+ title: newTitle,
39320
+ slide_count: newSlideCount,
39321
+ formats: newFormats
39322
+ });
39323
+ }
39324
+ }
39325
+ if (newStatus === "failed") {
39326
+ const errorMsg = data.error || "Job failed";
39327
+ setError(errorMsg);
39328
+ if (!hasNotifiedRef.current && onFailedRef.current) {
39329
+ hasNotifiedRef.current = true;
39330
+ onFailedRef.current(errorMsg);
39331
+ }
39254
39332
  }
39255
- if (newStatus === "failed" && data.error) setError(data.error);
39256
39333
  } catch {
39257
39334
  }
39258
39335
  };
@@ -39261,7 +39338,7 @@ var PresentationJobCard = ({
39261
39338
  return () => {
39262
39339
  if (intervalRef.current) clearInterval(intervalRef.current);
39263
39340
  };
39264
- }, [isTerminal, pollUrl]);
39341
+ }, [isTerminal, pollUrl, authToken, initialTitle]);
39265
39342
  (0, import_react75.useEffect)(() => {
39266
39343
  if (isTerminal && intervalRef.current) {
39267
39344
  clearInterval(intervalRef.current);
@@ -39280,18 +39357,63 @@ var PresentationJobCard = ({
39280
39357
  }
39281
39358
  };
39282
39359
  if (status === "pending" || status === "running") {
39283
- return /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: cn("w-full", className), children: /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "bg-zinc-900 border border-zinc-800 rounded-2xl p-5", children: [
39284
- /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "flex items-center gap-3 mb-5", children: [
39285
- /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(Skel, { className: "w-10 h-10 rounded-xl flex-shrink-0" }),
39286
- /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "flex-1 space-y-2", children: [
39287
- /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(Skel, { className: "h-3.5 w-44" }),
39288
- /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(Skel, { className: "h-3 w-28" })
39360
+ const stageMessage = getStageMessage(progress);
39361
+ return /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: cn("w-full", className), children: /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "bg-zinc-900 border border-zinc-800 rounded-2xl overflow-hidden", children: [
39362
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "h-1 bg-zinc-800", children: /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(
39363
+ "div",
39364
+ {
39365
+ className: "h-full bg-gradient-to-r from-indigo-500 via-violet-500 to-purple-500 transition-all duration-500 ease-out",
39366
+ style: { width: `${progress}%` }
39367
+ }
39368
+ ) }),
39369
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "p-5", children: [
39370
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "flex items-center gap-3 mb-5", children: [
39371
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "w-10 h-10 rounded-xl bg-indigo-500/10 border border-indigo-500/20 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(SlidesIcon, {}) }),
39372
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "flex-1 min-w-0", children: [
39373
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("p", { className: "text-sm font-semibold text-zinc-100 truncate leading-tight", children: title || "Generating presentation..." }),
39374
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("p", { className: "text-xs text-zinc-500 mt-0.5", children: "Creating slides..." })
39375
+ ] })
39376
+ ] }),
39377
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "rounded-2xl border border-zinc-800/70 bg-zinc-950/80 p-3 sm:p-4 mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "relative overflow-hidden rounded-xl bg-zinc-900 shadow-[0_0_0_1px_rgba(255,255,255,0.02)] aspect-[16/9] min-h-[320px] sm:min-h-[420px] lg:min-h-[500px]", children: [
39378
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "absolute inset-0 bg-[radial-gradient(circle_at_14%_16%,rgba(99,102,241,0.18),transparent_30%),radial-gradient(circle_at_86%_84%,rgba(168,85,247,0.16),transparent_28%),linear-gradient(135deg,rgba(50,54,86,0.96),rgba(18,18,30,0.98))]" }),
39379
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "absolute left-0 top-0 h-full w-[64%] bg-gradient-to-br from-indigo-500/90 via-violet-600/85 to-purple-700/90" }),
39380
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "absolute right-0 top-0 h-full w-[36%] bg-zinc-950/95" }),
39381
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "absolute left-[6%] top-[10%] h-24 w-24 rounded-full bg-white/8 blur-2xl" }),
39382
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "absolute right-[7%] bottom-[10%] h-28 w-28 rounded-full bg-white/6 blur-2xl" }),
39383
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "absolute left-[5%] top-[14%] h-5 w-32 rounded-full bg-white/10 animate-pulse" }),
39384
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "absolute left-[5%] top-[33%] h-4 w-[42%] rounded-full bg-white/12 animate-pulse", style: { animationDelay: "120ms" } }),
39385
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "absolute left-[5%] top-[40%] h-4 w-[35%] rounded-full bg-white/12 animate-pulse", style: { animationDelay: "220ms" } }),
39386
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "absolute left-[5%] bottom-[24%] h-5 w-[18%] rounded-full bg-white/12 animate-pulse", style: { animationDelay: "320ms" } }),
39387
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "absolute right-[6%] top-[14%] h-3 w-28 rounded-full bg-amber-300/70 animate-pulse", style: { animationDelay: "150ms" } }),
39388
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "absolute right-[6%] top-[28%] h-[84px] w-[72%] rounded-xl border border-amber-300/15 bg-white/5 animate-pulse", style: { animationDelay: "220ms" } }),
39389
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "absolute right-[6%] top-[50%] h-[84px] w-[72%] rounded-xl border border-violet-300/15 bg-white/5 animate-pulse", style: { animationDelay: "320ms" } }),
39390
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "absolute right-[6%] top-[72%] h-[84px] w-[72%] rounded-xl border border-purple-300/15 bg-white/5 animate-pulse", style: { animationDelay: "420ms" } }),
39391
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "absolute inset-x-0 bottom-0 flex items-center justify-between px-4 py-3 bg-gradient-to-t from-black/30 to-transparent", children: [
39392
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "flex items-center gap-2", children: [
39393
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { className: "h-8 w-8 rounded-full border border-zinc-600 bg-zinc-800/70 flex items-center justify-center text-zinc-400", children: /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(ChevronLeft2, {}) }),
39394
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { className: "text-sm text-zinc-300 font-medium tabular-nums", children: "1 / 1" }),
39395
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { className: "h-8 w-8 rounded-full border border-zinc-700 bg-zinc-800/50 flex items-center justify-center text-zinc-500 opacity-70", children: /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(ChevronRight2, {}) })
39396
+ ] }),
39397
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "flex items-center gap-2 text-xs text-zinc-400", children: [
39398
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { className: "inline-flex h-2 w-2 rounded-full bg-indigo-400 animate-pulse" }),
39399
+ "Building preview"
39400
+ ] })
39401
+ ] }),
39402
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "absolute inset-0 -translate-x-full animate-[shimmer_2s_infinite] bg-gradient-to-r from-transparent via-white/8 to-transparent" })
39403
+ ] }) }),
39404
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "flex items-center justify-between pt-4 border-t border-zinc-800/60", children: [
39405
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "flex items-center gap-2.5", children: [
39406
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("span", { className: "relative flex h-2 w-2", children: [
39407
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-indigo-500 opacity-75" }),
39408
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { className: "relative inline-flex rounded-full h-2 w-2 bg-indigo-500" })
39409
+ ] }),
39410
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { className: "text-xs text-indigo-400/80 font-medium", children: stageMessage })
39411
+ ] }),
39412
+ /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("span", { className: "text-xs text-zinc-500 tabular-nums font-medium", children: [
39413
+ progress,
39414
+ "%"
39415
+ ] })
39289
39416
  ] })
39290
- ] }),
39291
- /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "grid grid-cols-3 gap-3", children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(Skel, { className: "aspect-video rounded-lg", style: { animationDelay: `${i * 150}ms` } }, i)) }),
39292
- /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "flex items-center gap-2.5 mt-4 pt-4 border-t border-zinc-800/60", children: [
39293
- /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { className: "w-2 h-2 rounded-full bg-indigo-500 animate-pulse flex-shrink-0" }),
39294
- /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(Skel, { className: "h-3 w-36" })
39295
39417
  ] })
39296
39418
  ] }) });
39297
39419
  }
@@ -45694,11 +45816,14 @@ var PXEngineRenderer = ({
45694
45816
  props = {},
45695
45817
  children = [],
45696
45818
  id,
45819
+ key: _extractedKey,
45820
+ // Extract key to prevent React warning about spreading key prop
45697
45821
  ...remainingProps
45698
45822
  } = component;
45699
45823
  const componentName = name || type || componentType;
45700
45824
  if (!componentName || typeof componentName !== "string") return null;
45701
45825
  const rawProps = { ...remainingProps, ...props };
45826
+ delete rawProps.key;
45702
45827
  if (disabled !== void 0 && rawProps.disabled === void 0) {
45703
45828
  rawProps.disabled = disabled;
45704
45829
  }