pxengine 0.1.134 → 0.1.136

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.mjs CHANGED
@@ -15787,10 +15787,11 @@ var NextStepCard = ({
15787
15787
  };
15788
15788
 
15789
15789
  // src/molecules/generic/PresentationJobCard/PresentationJobCard.tsx
15790
- import { useCallback as useCallback4, useEffect as useEffect7, useRef as useRef9, useState as useState10 } from "react";
15790
+ import { useCallback as useCallback4, useEffect as useEffect8, useLayoutEffect as useLayoutEffect2, useRef as useRef10, useState as useState10 } from "react";
15791
15791
 
15792
15792
  // src/lib/shared-poll.ts
15793
15793
  import { useEffect as useEffect6, useRef as useRef8 } from "react";
15794
+ var SSE_FALLBACK_POLL_MS = 2e4;
15794
15795
  var MAX_RETAINED = 50;
15795
15796
  var RETAIN_TTL_MS = 30 * 60 * 1e3;
15796
15797
  var entries = /* @__PURE__ */ new Map();
@@ -15917,6 +15918,12 @@ function stopSharedPoll(key) {
15917
15918
  entry.stopped = true;
15918
15919
  clearTimer(entry);
15919
15920
  }
15921
+ function refreshSharedPoll(key) {
15922
+ if (!key) return;
15923
+ const entry = entries.get(key);
15924
+ if (!entry || entry.stopped) return;
15925
+ void runPoll(key);
15926
+ }
15920
15927
  function getSharedPollLastData(key) {
15921
15928
  if (!key) return void 0;
15922
15929
  const entry = entries.get(key);
@@ -15953,6 +15960,45 @@ function useSharedPoll(config, onData, onError) {
15953
15960
  }, [key, intervalMs]);
15954
15961
  }
15955
15962
 
15963
+ // src/lib/job-signal.ts
15964
+ import { useEffect as useEffect7, useRef as useRef9 } from "react";
15965
+ var JOB_SIGNAL_EVENT = "pxengine:job-signal";
15966
+ var listeners = /* @__PURE__ */ new Set();
15967
+ var windowBridgeInstalled = false;
15968
+ function fanout(jobId) {
15969
+ if (!jobId) return;
15970
+ for (const listener of Array.from(listeners)) {
15971
+ try {
15972
+ listener(jobId);
15973
+ } catch {
15974
+ }
15975
+ }
15976
+ }
15977
+ function ensureWindowBridge() {
15978
+ if (windowBridgeInstalled || typeof window === "undefined") return;
15979
+ windowBridgeInstalled = true;
15980
+ window.addEventListener(JOB_SIGNAL_EVENT, (event) => {
15981
+ const detail = event.detail;
15982
+ const jobId = detail?.jobId;
15983
+ if (typeof jobId === "string" && jobId) fanout(jobId);
15984
+ });
15985
+ }
15986
+ function emitJobSignal(jobId) {
15987
+ fanout(jobId);
15988
+ }
15989
+ function subscribeJobSignal(listener) {
15990
+ ensureWindowBridge();
15991
+ listeners.add(listener);
15992
+ return () => {
15993
+ listeners.delete(listener);
15994
+ };
15995
+ }
15996
+ function useJobSignal(onSignal) {
15997
+ const ref = useRef9(onSignal);
15998
+ ref.current = onSignal;
15999
+ useEffect7(() => subscribeJobSignal((jobId) => ref.current(jobId)), []);
16000
+ }
16001
+
15956
16002
  // src/molecules/generic/job-card-shared/Chip.tsx
15957
16003
  import { jsx as jsx148 } from "react/jsx-runtime";
15958
16004
  var Chip = ({
@@ -16044,6 +16090,40 @@ function formatTemplateLabel(templateId) {
16044
16090
  if (!templateId) return null;
16045
16091
  return templateId.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
16046
16092
  }
16093
+ var DECK_CANVAS = { w: 1280, h: 720 };
16094
+ function useDeckFitScale(canvasW = DECK_CANVAS.w, canvasH = DECK_CANVAS.h) {
16095
+ const containerRef = useRef10(null);
16096
+ const [scale, setScale] = useState10(1);
16097
+ useLayoutEffect2(() => {
16098
+ const el = containerRef.current;
16099
+ if (!el) return;
16100
+ const update = () => {
16101
+ const w = el.clientWidth;
16102
+ const h = el.clientHeight;
16103
+ if (w <= 0 || h <= 0) return;
16104
+ setScale(Math.min(w / canvasW, h / canvasH));
16105
+ };
16106
+ update();
16107
+ const ro = new ResizeObserver(update);
16108
+ ro.observe(el);
16109
+ return () => ro.disconnect();
16110
+ }, [canvasW, canvasH]);
16111
+ return { containerRef, scale, canvasW, canvasH };
16112
+ }
16113
+ function hideDeckChrome(iframe) {
16114
+ try {
16115
+ const doc = iframe?.contentDocument;
16116
+ if (!doc) return;
16117
+ let style = doc.getElementById("pxe-embed-chrome");
16118
+ if (!style) {
16119
+ style = doc.createElement("style");
16120
+ style.id = "pxe-embed-chrome";
16121
+ (doc.head || doc.documentElement).appendChild(style);
16122
+ }
16123
+ style.textContent = ".nav,.progress-bar,.dots{display:none!important}";
16124
+ } catch {
16125
+ }
16126
+ }
16047
16127
  function deriveJobStatusUrl(newJobId, pollUrl, regenerateUrl) {
16048
16128
  const base = pollUrl?.replace(/\/api\/jobs\/[^/]+\/status.*$/, "") ?? regenerateUrl?.replace(/\/api\/presentations\/[^/]+\/regenerate.*$/, "") ?? "";
16049
16129
  return `${base}/api/jobs/${newJobId}/status`;
@@ -16147,8 +16227,9 @@ var ExportModal = ({ formats, title, onClose }) => {
16147
16227
  var FullscreenModal = ({ url, title, slideCount, initialSlide = 1, onClose }) => {
16148
16228
  const [currentSlide, setCurrentSlide] = useState10(initialSlide);
16149
16229
  const [iframeReady, setIframeReady] = useState10(false);
16150
- const iframeRef = useRef9(null);
16151
- useEffect7(() => {
16230
+ const iframeRef = useRef10(null);
16231
+ const { containerRef, scale, canvasW, canvasH } = useDeckFitScale();
16232
+ useEffect8(() => {
16152
16233
  const onKey = (e) => {
16153
16234
  if (e.key === "Escape") onClose();
16154
16235
  };
@@ -16166,7 +16247,7 @@ var FullscreenModal = ({ url, title, slideCount, initialSlide = 1, onClose }) =>
16166
16247
  window.removeEventListener("message", onMsg);
16167
16248
  };
16168
16249
  }, [onClose, iframeReady]);
16169
- useEffect7(() => {
16250
+ useEffect8(() => {
16170
16251
  document.body.style.overflow = "hidden";
16171
16252
  return () => {
16172
16253
  document.body.style.overflow = "";
@@ -16230,19 +16311,33 @@ var FullscreenModal = ({ url, title, slideCount, initialSlide = 1, onClose }) =>
16230
16311
  )
16231
16312
  ] })
16232
16313
  ] }),
16233
- /* @__PURE__ */ jsx151("div", { className: "flex-1 relative", children: /* @__PURE__ */ jsx151(
16234
- "iframe",
16314
+ /* @__PURE__ */ jsx151("div", { ref: containerRef, className: "flex-1 relative flex items-center justify-center overflow-hidden", children: /* @__PURE__ */ jsx151(
16315
+ "div",
16235
16316
  {
16236
- ref: iframeRef,
16237
- src: url,
16238
- title,
16239
- onLoad: () => {
16240
- setIframeReady(true);
16241
- iframeRef.current?.contentWindow?.postMessage({ type: "goToSlide", slide: initialSlide }, "*");
16242
- },
16243
- sandbox: "allow-same-origin allow-scripts",
16244
- allow: "fullscreen",
16245
- className: "absolute inset-0 w-full h-full border-0"
16317
+ className: "relative",
16318
+ style: { width: canvasW * scale, height: canvasH * scale },
16319
+ children: /* @__PURE__ */ jsx151(
16320
+ "iframe",
16321
+ {
16322
+ ref: iframeRef,
16323
+ src: url,
16324
+ title,
16325
+ onLoad: () => {
16326
+ setIframeReady(true);
16327
+ hideDeckChrome(iframeRef.current);
16328
+ iframeRef.current?.contentWindow?.postMessage({ type: "goToSlide", slide: initialSlide }, "*");
16329
+ },
16330
+ sandbox: "allow-same-origin allow-scripts",
16331
+ allow: "fullscreen",
16332
+ className: "absolute top-0 left-0 border-0",
16333
+ style: {
16334
+ width: canvasW,
16335
+ height: canvasH,
16336
+ transform: `scale(${scale})`,
16337
+ transformOrigin: "top left"
16338
+ }
16339
+ }
16340
+ )
16246
16341
  }
16247
16342
  ) })
16248
16343
  ] });
@@ -16306,45 +16401,46 @@ var PresentationJobCard = ({
16306
16401
  const [regenPollUrl, setRegenPollUrl] = useState10(null);
16307
16402
  const [currentSlide, setCurrentSlide] = useState10(1);
16308
16403
  const [iframeReady, setIframeReady] = useState10(false);
16309
- const iframeRef = useRef9(null);
16310
- useEffect7(() => {
16404
+ const iframeRef = useRef10(null);
16405
+ const { containerRef: previewFitRef, scale: previewScale, canvasW, canvasH } = useDeckFitScale();
16406
+ useEffect8(() => {
16311
16407
  setStatus(initialStatus);
16312
16408
  }, [initialStatus]);
16313
16409
  const progressPct = initialProgress?.percentage;
16314
16410
  const progressStep = initialProgress?.current_step;
16315
- useEffect7(() => {
16411
+ useEffect8(() => {
16316
16412
  if (initialProgress) setProgress(initialProgress);
16317
16413
  }, [progressPct, progressStep]);
16318
- useEffect7(() => {
16414
+ useEffect8(() => {
16319
16415
  if (initialError) setError(initialError);
16320
16416
  }, [initialError]);
16321
- useEffect7(() => {
16417
+ useEffect8(() => {
16322
16418
  if (initialSlideCount !== void 0) setSlideCount(initialSlideCount);
16323
16419
  }, [initialSlideCount]);
16324
16420
  const htmlUrl = initialFormats?.html_url;
16325
- useEffect7(() => {
16421
+ useEffect8(() => {
16326
16422
  if (initialFormats) setFormats(initialFormats);
16327
16423
  }, [htmlUrl]);
16328
- useEffect7(() => {
16424
+ useEffect8(() => {
16329
16425
  if (initialTitle) setTitle(initialTitle);
16330
16426
  }, [initialTitle]);
16331
- useEffect7(() => {
16427
+ useEffect8(() => {
16332
16428
  if (initialGenerationMode) setGenerationMode(initialGenerationMode);
16333
16429
  }, [initialGenerationMode]);
16334
- useEffect7(() => {
16430
+ useEffect8(() => {
16335
16431
  if (initialTemplateId) setTemplateId(initialTemplateId);
16336
16432
  }, [initialTemplateId]);
16337
- useEffect7(() => {
16433
+ useEffect8(() => {
16338
16434
  if (initialTemplateVersionId) setTemplateVersionId(initialTemplateVersionId);
16339
16435
  }, [initialTemplateVersionId]);
16340
- useEffect7(() => {
16436
+ useEffect8(() => {
16341
16437
  if (initialReviewStatus) setReviewStatus(initialReviewStatus);
16342
16438
  }, [initialReviewStatus]);
16343
16439
  const initialOutlineSlideCount = initialOutline?.slides?.length;
16344
- useEffect7(() => {
16440
+ useEffect8(() => {
16345
16441
  if (initialOutline) setOutline(initialOutline);
16346
16442
  }, [initialOutlineSlideCount]);
16347
- useEffect7(() => {
16443
+ useEffect8(() => {
16348
16444
  if (reviewStatus !== "pending_outline_approval" || slideTemplateOptions !== null) return;
16349
16445
  let cancelled = false;
16350
16446
  (async () => {
@@ -16371,10 +16467,10 @@ var PresentationJobCard = ({
16371
16467
  cancelled = true;
16372
16468
  };
16373
16469
  }, [reviewStatus, slideTemplateOptions, templatesUrl, authToken]);
16374
- useEffect7(() => {
16470
+ useEffect8(() => {
16375
16471
  setIframeReady(false);
16376
16472
  }, [formats.html_url]);
16377
- useEffect7(() => {
16473
+ useEffect8(() => {
16378
16474
  const handler = (e) => {
16379
16475
  if (e.data?.type === "slideChanged") {
16380
16476
  setCurrentSlide(e.data.slide);
@@ -16400,15 +16496,15 @@ var PresentationJobCard = ({
16400
16496
  };
16401
16497
  const isTerminal = status === "complete" || status === "failed";
16402
16498
  const building = Boolean(outlineWritePollUrl) || approvingOutline;
16403
- const onCompleteRef = useRef9(onComplete);
16404
- const onFailedRef = useRef9(onFailed);
16405
- const hasNotifiedRef = useRef9(false);
16499
+ const onCompleteRef = useRef10(onComplete);
16500
+ const onFailedRef = useRef10(onFailed);
16501
+ const hasNotifiedRef = useRef10(false);
16406
16502
  onCompleteRef.current = onComplete;
16407
16503
  onFailedRef.current = onFailed;
16408
16504
  useSharedPoll(
16409
16505
  {
16410
16506
  key: !isTerminal && pollUrl ? pollUrl : null,
16411
- intervalMs: 3e3,
16507
+ intervalMs: SSE_FALLBACK_POLL_MS,
16412
16508
  fetcher: async () => {
16413
16509
  const headers = {};
16414
16510
  if (authToken) {
@@ -16468,7 +16564,7 @@ var PresentationJobCard = ({
16468
16564
  useSharedPoll(
16469
16565
  {
16470
16566
  key: building && pollUrl ? pollUrl : null,
16471
- intervalMs: 2e3,
16567
+ intervalMs: SSE_FALLBACK_POLL_MS,
16472
16568
  fetcher: async () => {
16473
16569
  const headers = {};
16474
16570
  if (authToken) headers["Authorization"] = `Bearer ${authToken}`;
@@ -16518,7 +16614,7 @@ var PresentationJobCard = ({
16518
16614
  useSharedPoll(
16519
16615
  {
16520
16616
  key: outlineWritePollUrl,
16521
- intervalMs: 3e3,
16617
+ intervalMs: SSE_FALLBACK_POLL_MS,
16522
16618
  fetcher: async () => {
16523
16619
  const headers = {};
16524
16620
  if (authToken) headers["Authorization"] = `Bearer ${authToken}`;
@@ -16543,7 +16639,7 @@ var PresentationJobCard = ({
16543
16639
  useSharedPoll(
16544
16640
  {
16545
16641
  key: regenPollUrl,
16546
- intervalMs: 3e3,
16642
+ intervalMs: SSE_FALLBACK_POLL_MS,
16547
16643
  fetcher: async () => {
16548
16644
  const headers = {};
16549
16645
  if (authToken) headers["Authorization"] = `Bearer ${authToken}`;
@@ -16565,6 +16661,16 @@ var PresentationJobCard = ({
16565
16661
  }
16566
16662
  }
16567
16663
  );
16664
+ useJobSignal(
16665
+ useCallback4(
16666
+ (completedJobId) => {
16667
+ for (const url of [pollUrl, outlineWritePollUrl, regenPollUrl]) {
16668
+ if (url && url.includes(completedJobId)) refreshSharedPoll(url);
16669
+ }
16670
+ },
16671
+ [pollUrl, outlineWritePollUrl, regenPollUrl]
16672
+ )
16673
+ );
16568
16674
  const buildEditedOutline = () => {
16569
16675
  if (!outline || !Array.isArray(outline.slides)) return void 0;
16570
16676
  let changed = false;
@@ -17167,19 +17273,36 @@ var PresentationJobCard = ({
17167
17273
  /* @__PURE__ */ jsxs109(
17168
17274
  "div",
17169
17275
  {
17276
+ ref: previewFitRef,
17170
17277
  onClick: () => setShowFullscreen(true),
17171
- className: "group relative aspect-video w-full overflow-hidden rounded-xl bg-zinc-950 border border-zinc-800/50 cursor-pointer",
17278
+ className: "group relative aspect-video w-full overflow-hidden rounded-xl bg-zinc-950 border border-zinc-800/50 cursor-pointer flex items-center justify-center",
17172
17279
  title: "Click to open fullscreen",
17173
17280
  children: [
17174
17281
  /* @__PURE__ */ jsx151(
17175
- "iframe",
17282
+ "div",
17176
17283
  {
17177
- ref: iframeRef,
17178
- src: formats.html_url,
17179
- title,
17180
- sandbox: "allow-same-origin allow-scripts",
17181
- onLoad: () => setIframeReady(true),
17182
- className: "absolute inset-0 block h-full w-full border-0 pointer-events-none"
17284
+ className: "relative",
17285
+ style: { width: canvasW * previewScale, height: canvasH * previewScale },
17286
+ children: /* @__PURE__ */ jsx151(
17287
+ "iframe",
17288
+ {
17289
+ ref: iframeRef,
17290
+ src: formats.html_url,
17291
+ title,
17292
+ sandbox: "allow-same-origin allow-scripts",
17293
+ onLoad: () => {
17294
+ setIframeReady(true);
17295
+ hideDeckChrome(iframeRef.current);
17296
+ },
17297
+ className: "absolute top-0 left-0 border-0 pointer-events-none",
17298
+ style: {
17299
+ width: canvasW,
17300
+ height: canvasH,
17301
+ transform: `scale(${previewScale})`,
17302
+ transformOrigin: "top left"
17303
+ }
17304
+ }
17305
+ )
17183
17306
  }
17184
17307
  ),
17185
17308
  /* @__PURE__ */ jsx151("div", { className: "absolute inset-0 flex items-center justify-center bg-black/0 group-hover:bg-black/30 transition-colors", children: /* @__PURE__ */ jsxs109("span", { className: "opacity-0 group-hover:opacity-100 transition-opacity flex items-center gap-2 bg-zinc-900/80 backdrop-blur-sm border border-zinc-700 rounded-lg px-3 py-1.5 text-xs text-zinc-200 font-medium", children: [
@@ -17240,7 +17363,7 @@ var PresentationJobCard = ({
17240
17363
  };
17241
17364
 
17242
17365
  // src/molecules/generic/ResearchReportJobCard/ResearchReportJobCard.tsx
17243
- import { useCallback as useCallback5, useEffect as useEffect8, useRef as useRef10, useState as useState11 } from "react";
17366
+ import { useCallback as useCallback5, useEffect as useEffect9, useRef as useRef11, useState as useState11 } from "react";
17244
17367
  import { Fragment as Fragment6, jsx as jsx152, jsxs as jsxs110 } from "react/jsx-runtime";
17245
17368
  var DEFAULT_THEME = {
17246
17369
  primary: "#C0AE82",
@@ -17276,14 +17399,14 @@ function withPdfViewerParams(url) {
17276
17399
  return `${url}#toolbar=0&navpanes=0&scrollbar=0`;
17277
17400
  }
17278
17401
  var FullscreenPreviewModal = ({ url, title, onClose, isPdf }) => {
17279
- useEffect8(() => {
17402
+ useEffect9(() => {
17280
17403
  const onKey = (e) => {
17281
17404
  if (e.key === "Escape") onClose();
17282
17405
  };
17283
17406
  document.addEventListener("keydown", onKey);
17284
17407
  return () => document.removeEventListener("keydown", onKey);
17285
17408
  }, [onClose]);
17286
- useEffect8(() => {
17409
+ useEffect9(() => {
17287
17410
  document.body.style.overflow = "hidden";
17288
17411
  return () => {
17289
17412
  document.body.style.overflow = "";
@@ -17341,7 +17464,7 @@ var ReportExportModal = ({ htmlUrl, pdfUrl, title, onClose }) => {
17341
17464
  const available = REPORT_FORMATS.filter((f) => urls[f.key]);
17342
17465
  const filename = (title ?? "").replace(/[^a-z0-9]/gi, "-").toLowerCase();
17343
17466
  const [downloadingKey, setDownloadingKey] = useState11(null);
17344
- useEffect8(() => {
17467
+ useEffect9(() => {
17345
17468
  const onKey = (e) => {
17346
17469
  if (e.key === "Escape") onClose();
17347
17470
  };
@@ -17487,62 +17610,62 @@ var ResearchReportJobCard = (props) => {
17487
17610
  const [rowError, setRowError] = useState11(null);
17488
17611
  const [outlineWritePollUrl, setOutlineWritePollUrl] = useState11(null);
17489
17612
  const [regenPollUrl, setRegenPollUrl] = useState11(null);
17490
- const onCompleteRef = useRef10(onComplete);
17491
- const onFailedRef = useRef10(onFailed);
17492
- const hasNotifiedRef = useRef10(false);
17613
+ const onCompleteRef = useRef11(onComplete);
17614
+ const onFailedRef = useRef11(onFailed);
17615
+ const hasNotifiedRef = useRef11(false);
17493
17616
  onCompleteRef.current = onComplete;
17494
17617
  onFailedRef.current = onFailed;
17495
- useEffect8(() => {
17618
+ useEffect9(() => {
17496
17619
  const newStatus = initialStatus ?? (initialHtmlUrl ? "complete" : void 0);
17497
17620
  setStatus(newStatus);
17498
17621
  }, [initialStatus, initialHtmlUrl]);
17499
- useEffect8(() => {
17622
+ useEffect9(() => {
17500
17623
  if (initialTitle) setTitle(initialTitle);
17501
17624
  }, [initialTitle]);
17502
- useEffect8(() => {
17625
+ useEffect9(() => {
17503
17626
  if (initialHtmlUrl) setHtmlUrl(initialHtmlUrl);
17504
17627
  }, [initialHtmlUrl]);
17505
- useEffect8(() => {
17628
+ useEffect9(() => {
17506
17629
  if (initialGenerationMode) setGenerationMode(initialGenerationMode);
17507
17630
  }, [initialGenerationMode]);
17508
- useEffect8(() => {
17631
+ useEffect9(() => {
17509
17632
  if (initialTemplateId) setTemplateId(initialTemplateId);
17510
17633
  }, [initialTemplateId]);
17511
- useEffect8(() => {
17634
+ useEffect9(() => {
17512
17635
  if (initialTemplateVersionId) setTemplateVersionId(initialTemplateVersionId);
17513
17636
  }, [initialTemplateVersionId]);
17514
- useEffect8(() => {
17637
+ useEffect9(() => {
17515
17638
  if (initialReviewStatus) setReviewStatus(initialReviewStatus);
17516
17639
  }, [initialReviewStatus]);
17517
17640
  const initialOutlineSectionCount = initialOutline?.sections?.length;
17518
- useEffect8(() => {
17641
+ useEffect9(() => {
17519
17642
  if (initialOutline) setOutline(initialOutline);
17520
17643
  }, [initialOutlineSectionCount]);
17521
- useEffect8(() => {
17644
+ useEffect9(() => {
17522
17645
  if (initialDepth) setDepth(initialDepth);
17523
17646
  }, [initialDepth]);
17524
- useEffect8(() => {
17647
+ useEffect9(() => {
17525
17648
  if (initialSectionCount !== void 0) setSectionCount(initialSectionCount);
17526
17649
  }, [initialSectionCount]);
17527
- useEffect8(() => {
17650
+ useEffect9(() => {
17528
17651
  if (initialSourceCount !== void 0) setSourceCount(initialSourceCount);
17529
17652
  }, [initialSourceCount]);
17530
- useEffect8(() => {
17653
+ useEffect9(() => {
17531
17654
  if (initialWordCount !== void 0) setWordCount(initialWordCount);
17532
17655
  }, [initialWordCount]);
17533
- useEffect8(() => {
17656
+ useEffect9(() => {
17534
17657
  if (initialSummary) setSummary(initialSummary);
17535
17658
  }, [initialSummary]);
17536
17659
  const themePrimary = initialTheme?.primary;
17537
- useEffect8(() => {
17660
+ useEffect9(() => {
17538
17661
  if (initialTheme) setTheme(initialTheme);
17539
17662
  }, [themePrimary]);
17540
- useEffect8(() => {
17663
+ useEffect9(() => {
17541
17664
  if (initialError) setError(initialError);
17542
17665
  }, [initialError]);
17543
17666
  const progressPct = initialProgress?.percentage;
17544
17667
  const progressStep = initialProgress?.current_step;
17545
- useEffect8(() => {
17668
+ useEffect9(() => {
17546
17669
  if (initialProgress) setProgress(initialProgress);
17547
17670
  }, [progressPct, progressStep]);
17548
17671
  const isTerminal = status === "complete" || status === "failed";
@@ -17552,7 +17675,7 @@ var ResearchReportJobCard = (props) => {
17552
17675
  useSharedPoll(
17553
17676
  {
17554
17677
  key: !isTerminal && pollUrl ? pollUrl : null,
17555
- intervalMs: 3e3,
17678
+ intervalMs: SSE_FALLBACK_POLL_MS,
17556
17679
  fetcher: async () => {
17557
17680
  const headers = {};
17558
17681
  if (authToken) {
@@ -17608,7 +17731,7 @@ var ResearchReportJobCard = (props) => {
17608
17731
  useSharedPoll(
17609
17732
  {
17610
17733
  key: building && pollUrl ? pollUrl : null,
17611
- intervalMs: 2e3,
17734
+ intervalMs: SSE_FALLBACK_POLL_MS,
17612
17735
  fetcher: async () => {
17613
17736
  const headers = {};
17614
17737
  if (authToken) headers["Authorization"] = `Bearer ${authToken}`;
@@ -17655,7 +17778,7 @@ var ResearchReportJobCard = (props) => {
17655
17778
  useSharedPoll(
17656
17779
  {
17657
17780
  key: regenPollUrl,
17658
- intervalMs: 3e3,
17781
+ intervalMs: SSE_FALLBACK_POLL_MS,
17659
17782
  fetcher: async () => {
17660
17783
  const headers = {};
17661
17784
  if (authToken) headers["Authorization"] = `Bearer ${authToken}`;
@@ -17710,7 +17833,7 @@ var ResearchReportJobCard = (props) => {
17710
17833
  useSharedPoll(
17711
17834
  {
17712
17835
  key: outlineWritePollUrl,
17713
- intervalMs: 3e3,
17836
+ intervalMs: SSE_FALLBACK_POLL_MS,
17714
17837
  fetcher: async () => {
17715
17838
  const headers = {};
17716
17839
  if (authToken) headers["Authorization"] = `Bearer ${authToken}`;
@@ -17732,6 +17855,16 @@ var ResearchReportJobCard = (props) => {
17732
17855
  }
17733
17856
  }
17734
17857
  );
17858
+ useJobSignal(
17859
+ useCallback5(
17860
+ (completedJobId) => {
17861
+ for (const url of [pollUrl, outlineWritePollUrl, regenPollUrl]) {
17862
+ if (url && url.includes(completedJobId)) refreshSharedPoll(url);
17863
+ }
17864
+ },
17865
+ [pollUrl, outlineWritePollUrl, regenPollUrl]
17866
+ )
17867
+ );
17735
17868
  const buildEditedOutline = () => {
17736
17869
  if (!outline || !Array.isArray(outline.sections)) return void 0;
17737
17870
  let changed = false;
@@ -18405,7 +18538,7 @@ var ResearchReportJobCard = (props) => {
18405
18538
  };
18406
18539
 
18407
18540
  // src/molecules/generic/WebSearchJobCard/WebSearchJobCard.tsx
18408
- import { useEffect as useEffect9, useRef as useRef11, useState as useState12 } from "react";
18541
+ import { useEffect as useEffect10, useRef as useRef12, useState as useState12 } from "react";
18409
18542
  import { jsx as jsx153, jsxs as jsxs111 } from "react/jsx-runtime";
18410
18543
  var SearchIcon = () => /* @__PURE__ */ jsxs111("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
18411
18544
  /* @__PURE__ */ jsx153("circle", { cx: "11", cy: "11", r: "8" }),
@@ -18442,38 +18575,38 @@ var WebSearchJobCard = ({
18442
18575
  const [results, setResults] = useState12(initialResults || []);
18443
18576
  const [error, setError] = useState12(initialError);
18444
18577
  const [progress, setProgress] = useState12(initialProgress);
18445
- const onCompleteRef = useRef11(onComplete);
18446
- const onFailedRef = useRef11(onFailed);
18447
- const hasNotifiedRef = useRef11(false);
18578
+ const onCompleteRef = useRef12(onComplete);
18579
+ const onFailedRef = useRef12(onFailed);
18580
+ const hasNotifiedRef = useRef12(false);
18448
18581
  onCompleteRef.current = onComplete;
18449
18582
  onFailedRef.current = onFailed;
18450
- useEffect9(() => {
18583
+ useEffect10(() => {
18451
18584
  setStatus(initialStatus);
18452
18585
  }, [initialStatus]);
18453
- useEffect9(() => {
18586
+ useEffect10(() => {
18454
18587
  if (initialQuery) setQuery(initialQuery);
18455
18588
  }, [initialQuery]);
18456
- useEffect9(() => {
18589
+ useEffect10(() => {
18457
18590
  if (initialTitle && !initialQuery) setQuery(initialTitle);
18458
18591
  }, [initialTitle, initialQuery]);
18459
- useEffect9(() => {
18592
+ useEffect10(() => {
18460
18593
  if (initialResultCount !== void 0) setResultCount(initialResultCount);
18461
18594
  }, [initialResultCount]);
18462
- useEffect9(() => {
18595
+ useEffect10(() => {
18463
18596
  if (initialSearchCount !== void 0) setSearchCount(initialSearchCount);
18464
18597
  }, [initialSearchCount]);
18465
- useEffect9(() => {
18598
+ useEffect10(() => {
18466
18599
  if (initialSummary) setSummary(initialSummary);
18467
18600
  }, [initialSummary]);
18468
- useEffect9(() => {
18601
+ useEffect10(() => {
18469
18602
  if (initialResults) setResults(initialResults);
18470
18603
  }, [initialResults]);
18471
- useEffect9(() => {
18604
+ useEffect10(() => {
18472
18605
  if (initialError) setError(initialError);
18473
18606
  }, [initialError]);
18474
18607
  const progressPct = initialProgress?.percentage;
18475
18608
  const progressStep = initialProgress?.current_step;
18476
- useEffect9(() => {
18609
+ useEffect10(() => {
18477
18610
  if (initialProgress) setProgress(initialProgress);
18478
18611
  }, [progressPct, progressStep]);
18479
18612
  const isTerminal = status === "complete" || status === "failed";
@@ -18661,7 +18794,7 @@ var WebSearchJobCard = ({
18661
18794
  import React112, { useMemo as useMemo6 } from "react";
18662
18795
 
18663
18796
  // src/molecules/creator-discovery/SearchSpecCard/CustomFieldRenderers.tsx
18664
- import { useState as useState13, useRef as useRef12, useEffect as useEffect10, useMemo as useMemo5 } from "react";
18797
+ import { useState as useState13, useRef as useRef13, useEffect as useEffect11, useMemo as useMemo5 } from "react";
18665
18798
 
18666
18799
  // src/lib/countries.ts
18667
18800
  var countries = [
@@ -18875,8 +19008,8 @@ var CountrySelectEdit = ({
18875
19008
  }) => {
18876
19009
  const [isDropdownOpen, setIsDropdownOpen] = useState13(false);
18877
19010
  const [searchTerm, setSearchTerm] = useState13("");
18878
- const dropdownRef = useRef12(null);
18879
- useEffect10(() => {
19011
+ const dropdownRef = useRef13(null);
19012
+ useEffect11(() => {
18880
19013
  const handleClickOutside = (event) => {
18881
19014
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
18882
19015
  setIsDropdownOpen(false);
@@ -20945,11 +21078,11 @@ CampaignConceptCard.displayName = "CampaignConceptCard";
20945
21078
  import { useCallback as useCallback9, useState as useState22, memo } from "react";
20946
21079
 
20947
21080
  // src/molecules/creator-discovery/CreatorWidget/CreatorImageList.tsx
20948
- import { useEffect as useEffect11, useState as useState15 } from "react";
21081
+ import { useEffect as useEffect12, useState as useState15 } from "react";
20949
21082
  import { Fragment as Fragment7, jsx as jsx170, jsxs as jsxs127 } from "react/jsx-runtime";
20950
21083
  function useMediaQuery(query) {
20951
21084
  const [matches, setMatches] = useState15(false);
20952
- useEffect11(() => {
21085
+ useEffect12(() => {
20953
21086
  const media = window.matchMedia(query);
20954
21087
  const listener = () => setMatches(media.matches);
20955
21088
  listener();
@@ -21032,7 +21165,7 @@ function CreatorImageList({
21032
21165
  }
21033
21166
 
21034
21167
  // src/molecules/creator-discovery/CreatorWidget/CreatorProgressBar.tsx
21035
- import { useEffect as useEffect12, useState as useState16 } from "react";
21168
+ import { useEffect as useEffect13, useState as useState16 } from "react";
21036
21169
  import { motion as motion2, AnimatePresence as AnimatePresence2 } from "framer-motion";
21037
21170
  import { jsx as jsx171, jsxs as jsxs128 } from "react/jsx-runtime";
21038
21171
  function truncateName(name, maxLength) {
@@ -21041,7 +21174,7 @@ function truncateName(name, maxLength) {
21041
21174
  }
21042
21175
  function ProgressBar({ overallPercentage }) {
21043
21176
  const [showTooltip, setShowTooltip] = useState16(true);
21044
- useEffect12(() => {
21177
+ useEffect13(() => {
21045
21178
  if (overallPercentage && overallPercentage >= 100) {
21046
21179
  setShowTooltip(false);
21047
21180
  }
@@ -21202,7 +21335,7 @@ function CreatorCompactView({
21202
21335
  }
21203
21336
 
21204
21337
  // src/molecules/creator-discovery/CreatorWidget/CreatorExpandedPanel.tsx
21205
- import { useState as useState20, useEffect as useEffect14, useCallback as useCallback7 } from "react";
21338
+ import { useState as useState20, useEffect as useEffect15, useCallback as useCallback7 } from "react";
21206
21339
  import ReactDOM2 from "react-dom";
21207
21340
  import { AnimatePresence as AnimatePresence4, motion as motion5 } from "framer-motion";
21208
21341
 
@@ -22163,7 +22296,7 @@ function BrandCollaborationsList({
22163
22296
  }
22164
22297
 
22165
22298
  // src/molecules/creator-discovery/CreatorWidget/CreatorGridView.tsx
22166
- import { useState as useState19, useMemo as useMemo10, useRef as useRef13, useCallback as useCallback6, useEffect as useEffect13 } from "react";
22299
+ import { useState as useState19, useMemo as useMemo10, useRef as useRef14, useCallback as useCallback6, useEffect as useEffect14 } from "react";
22167
22300
  import { motion as motion4 } from "framer-motion";
22168
22301
  import { jsx as jsx179, jsxs as jsxs135 } from "react/jsx-runtime";
22169
22302
  var formatFollowerCount3 = (count) => {
@@ -22215,17 +22348,17 @@ function CreatorGridViewCard({ creator }) {
22215
22348
  const [isExpanded, setIsExpanded] = useState19(false);
22216
22349
  const [showFullDescription, setShowFullDescription] = useState19(false);
22217
22350
  const [isDescriptionOverflowing, setIsDescriptionOverflowing] = useState19(false);
22218
- const descriptionRef = useRef13(null);
22219
- const cardRef = useRef13(null);
22351
+ const descriptionRef = useRef14(null);
22352
+ const cardRef = useRef14(null);
22220
22353
  const checkDescriptionOverflow = useCallback6(() => {
22221
22354
  const el = descriptionRef.current;
22222
22355
  if (!el) return;
22223
22356
  setIsDescriptionOverflowing(el.scrollHeight > el.clientHeight + 1);
22224
22357
  }, []);
22225
- useEffect13(() => {
22358
+ useEffect14(() => {
22226
22359
  checkDescriptionOverflow();
22227
22360
  }, [checkDescriptionOverflow, isExpanded, showFullDescription]);
22228
- useEffect13(() => {
22361
+ useEffect14(() => {
22229
22362
  const onResize = () => checkDescriptionOverflow();
22230
22363
  window.addEventListener("resize", onResize);
22231
22364
  return () => window.removeEventListener("resize", onResize);
@@ -22917,7 +23050,7 @@ function CreatorExpandedPanel({
22917
23050
  setLoading(false);
22918
23051
  }
22919
23052
  }, [creatorIds, sessionId, version, fetcher]);
22920
- useEffect14(() => {
23053
+ useEffect15(() => {
22921
23054
  if (isOpen && creatorIds.length > 0) {
22922
23055
  loadCreators();
22923
23056
  }
@@ -22971,7 +23104,7 @@ function CreatorExpandedPanel({
22971
23104
  }
22972
23105
 
22973
23106
  // src/molecules/creator-discovery/CreatorWidget/useCreatorWidgetPolling.ts
22974
- import { useState as useState21, useEffect as useEffect15, useCallback as useCallback8, useMemo as useMemo11, useRef as useRef14 } from "react";
23107
+ import { useState as useState21, useEffect as useEffect16, useCallback as useCallback8, useMemo as useMemo11, useRef as useRef15 } from "react";
22975
23108
  var DEFAULT_POLLING_CONFIG = {
22976
23109
  pollInterval: 5e3,
22977
23110
  maxDuration: 15 * 60 * 1e3,
@@ -23049,9 +23182,9 @@ function useCreatorWidgetPolling({
23049
23182
  const [loadingStatus, setLoadingStatus] = useState21(
23050
23183
  !(hydrated.versionData && hydratedTerminal)
23051
23184
  );
23052
- const remainingTimeRef = useRef14(0);
23053
- const countdownRef = useRef14(null);
23054
- const versionDataRef = useRef14(versionData);
23185
+ const remainingTimeRef = useRef15(0);
23186
+ const countdownRef = useRef15(null);
23187
+ const versionDataRef = useRef15(versionData);
23055
23188
  versionDataRef.current = versionData;
23056
23189
  const requestedVersion = selectedVersion ?? currentVersion ?? versionData?.currentVersion;
23057
23190
  const updateStatus = useCallback8(
@@ -23092,9 +23225,9 @@ function useCreatorWidgetPolling({
23092
23225
  );
23093
23226
  const activeVersion = selectedVersion ?? requestedVersion;
23094
23227
  const statusKey = sessionId && activeVersion != null ? statusPollKey(sessionId, activeVersion) : null;
23095
- const errorCountRef = useRef14(0);
23096
- const deadlineRef = useRef14(0);
23097
- const doneRef = useRef14(hydratedTerminal);
23228
+ const errorCountRef = useRef15(0);
23229
+ const deadlineRef = useRef15(0);
23230
+ const doneRef = useRef15(hydratedTerminal);
23098
23231
  const stopCountdown = useCallback8(() => {
23099
23232
  if (countdownRef.current) {
23100
23233
  clearInterval(countdownRef.current);
@@ -23102,7 +23235,7 @@ function useCreatorWidgetPolling({
23102
23235
  }
23103
23236
  setTimeDisplay("");
23104
23237
  }, []);
23105
- useEffect15(() => {
23238
+ useEffect16(() => {
23106
23239
  if (statusKey == null) return;
23107
23240
  const cached = getSharedPollLastData(statusKey);
23108
23241
  const cachedStatus = cached?.status?.status;
@@ -23292,7 +23425,7 @@ function CreatorWidgetInner({
23292
23425
  var CreatorWidget = memo(CreatorWidgetInner);
23293
23426
 
23294
23427
  // src/molecules/analytics/AnalyticsChart.tsx
23295
- import { useEffect as useEffect16, useMemo as useMemo12, useRef as useRef15, useState as useState23 } from "react";
23428
+ import { useEffect as useEffect17, useMemo as useMemo12, useRef as useRef16, useState as useState23 } from "react";
23296
23429
 
23297
23430
  // src/molecules/analytics/buildOptions.ts
23298
23431
  function deepMerge(base, override) {
@@ -23628,8 +23761,8 @@ function AnalyticsChart({
23628
23761
  const [fetchedConfig, setFetchedConfig] = useState23(null);
23629
23762
  const [fetching, setFetching] = useState23(false);
23630
23763
  const [fetchError, setFetchError] = useState23(null);
23631
- const containerRef = useRef15(null);
23632
- const chartRef = useRef15(null);
23764
+ const containerRef = useRef16(null);
23765
+ const chartRef = useRef16(null);
23633
23766
  const declarative = useMemo12(
23634
23767
  () => resolveDeclarativeConfig({
23635
23768
  chartConfig,
@@ -23670,10 +23803,10 @@ function AnalyticsChart({
23670
23803
  const options = buildChartOptions(declarative, palette);
23671
23804
  return extraOptions ? deepMerge(options, extraOptions) : options;
23672
23805
  }, [declarative, theme, mode, extraOptions]);
23673
- useEffect16(() => {
23806
+ useEffect17(() => {
23674
23807
  setMounted(true);
23675
23808
  }, []);
23676
- useEffect16(() => {
23809
+ useEffect17(() => {
23677
23810
  if (!chartId || configProp || builtConfig) return;
23678
23811
  let cancelled = false;
23679
23812
  setFetching(true);
@@ -23695,7 +23828,7 @@ function AnalyticsChart({
23695
23828
  };
23696
23829
  }, [chartId, apiBase, authToken, configProp, builtConfig]);
23697
23830
  const activeConfig = configProp ?? builtConfig ?? fetchedConfig;
23698
- useEffect16(() => {
23831
+ useEffect17(() => {
23699
23832
  if (!mounted || !activeConfig || !containerRef.current) return;
23700
23833
  const container = containerRef.current;
23701
23834
  let cancelled = false;
@@ -23715,7 +23848,7 @@ function AnalyticsChart({
23715
23848
  cancelled = true;
23716
23849
  };
23717
23850
  }, [mounted, activeConfig]);
23718
- useEffect16(() => {
23851
+ useEffect17(() => {
23719
23852
  return () => {
23720
23853
  if (chartRef.current) {
23721
23854
  try {
@@ -23726,7 +23859,7 @@ function AnalyticsChart({
23726
23859
  }
23727
23860
  };
23728
23861
  }, []);
23729
- useEffect16(() => {
23862
+ useEffect17(() => {
23730
23863
  if (!mounted || !containerRef.current) return;
23731
23864
  const obs = new ResizeObserver(() => {
23732
23865
  try {
@@ -26002,6 +26135,7 @@ export {
26002
26135
  InputWidget,
26003
26136
  InsightDigestCard,
26004
26137
  InsightSummaryCard,
26138
+ JOB_SIGNAL_EVENT,
26005
26139
  KPIStatsCard,
26006
26140
  KbdAtom,
26007
26141
  KeywordBundlesDisplay,
@@ -26062,6 +26196,7 @@ export {
26062
26196
  ResizablePanel,
26063
26197
  ResizablePanelGroup,
26064
26198
  RiskSignalCard,
26199
+ SSE_FALLBACK_POLL_MS,
26065
26200
  ScoreBreakdownCard,
26066
26201
  ScrollArea,
26067
26202
  ScrollAreaAtom,
@@ -26132,17 +26267,21 @@ export {
26132
26267
  defaultFetchSelections,
26133
26268
  defaultPersistSelection,
26134
26269
  elementToQAField,
26270
+ emitJobSignal,
26135
26271
  formatQAMessage,
26136
26272
  generateFieldsFromData,
26137
26273
  generateFieldsFromPropDefinitions,
26138
26274
  getPxAuthToken,
26139
26275
  isInputAtom,
26140
26276
  notifyPxUnauthorized,
26277
+ refreshSharedPoll,
26141
26278
  setPxAuthTokenProvider,
26142
26279
  setPxUnauthorizedHandler,
26143
26280
  submitWidgetToAgent,
26281
+ subscribeJobSignal,
26144
26282
  th,
26145
26283
  useCreatorWidgetPolling,
26284
+ useJobSignal,
26146
26285
  useWidgetTheme,
26147
26286
  withAlpha
26148
26287
  };