@tscircuit/runframe 0.0.558 → 0.0.560

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.
@@ -1105,7 +1105,7 @@ var RenderLogViewer = ({
1105
1105
  };
1106
1106
 
1107
1107
  // package.json
1108
- var version = "0.0.557";
1108
+ var version = "0.0.559";
1109
1109
 
1110
1110
  // lib/components/CircuitJsonPreview/CircuitJsonPreview.tsx
1111
1111
  import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
@@ -1146,7 +1146,8 @@ var CircuitJsonPreview = ({
1146
1146
  autoRotate3dViewerDisabled,
1147
1147
  showSchematicDebugGrid = false,
1148
1148
  showToggleFullScreen = true,
1149
- defaultToFullScreen = false
1149
+ defaultToFullScreen = false,
1150
+ activeEffectName
1150
1151
  }) => {
1151
1152
  useStyles();
1152
1153
  const circuitJsonErrors = useMemo2(() => {
@@ -1213,7 +1214,7 @@ var CircuitJsonPreview = ({
1213
1214
  !leftHeaderContent && isRunningCode && /* @__PURE__ */ jsx16(Loader2, { className: "rf-w-4 rf-h-4 rf-animate-spin" }),
1214
1215
  !leftHeaderContent && /* @__PURE__ */ jsx16("div", { className: "rf-flex-grow" }),
1215
1216
  renderLog && renderLog.progress !== 1 && !errorMessage && /* @__PURE__ */ jsxs12("div", { className: "rf-flex rf-items-center rf-gap-2", children: [
1216
- renderLog.lastRenderEvent && /* @__PURE__ */ jsx16("div", { className: "rf-text-xs rf-text-gray-500", children: renderLog.lastRenderEvent?.phase ?? "" }),
1217
+ activeEffectName ? /* @__PURE__ */ jsx16("div", { className: "rf-text-xs rf-text-gray-500", children: activeEffectName }) : renderLog.lastRenderEvent && /* @__PURE__ */ jsx16("div", { className: "rf-text-xs rf-text-gray-500", children: renderLog.lastRenderEvent?.phase ?? "" }),
1217
1218
  /* @__PURE__ */ jsx16("div", { className: "rf-w-4 rf-h-4 rf-bg-blue-500 rf-opacity-50 rf-rounded-full rf-text-white", children: /* @__PURE__ */ jsx16(LoaderCircleIcon, { className: "rf-w-4 rf-h-4 rf-animate-spin" }) }),
1218
1219
  /* @__PURE__ */ jsxs12("div", { className: "rf-text-xs rf-font-bold rf-text-gray-700 rf-tabular-nums", children: [
1219
1220
  ((renderLog.progress ?? 0) * 100).toFixed(1),
package/dist/preview.d.ts CHANGED
@@ -67,6 +67,10 @@ interface PreviewContentProps {
67
67
  hasCodeChangedSinceLastRun?: boolean;
68
68
  defaultActiveTab?: TabId;
69
69
  renderLog?: RenderLog | null;
70
+ /**
71
+ * Name of the currently running async effect from @tscircuit/core, if any
72
+ */
73
+ activeEffectName?: string;
70
74
  onEditEvent?: (editEvent: ManualEditEvent) => void;
71
75
  editEvents?: ManualEditEvent[];
72
76
  onActiveTabChange?: (tab: TabId) => any;
@@ -83,7 +87,7 @@ declare global {
83
87
  }
84
88
  }
85
89
 
86
- declare const CircuitJsonPreview: ({ code, onRunClicked, errorMessage, errorStack, circuitJson, autoroutingGraphics, showRightHeaderContent, showCodeTab, codeTabContent, showJsonTab, showRenderLogTab, onActiveTabChange, renderLog, showImportAndFormatButtons, className, headerClassName, leftHeaderContent, readOnly, isStreaming, autoroutingLog, onReportAutoroutingLog, isRunningCode, hasCodeChangedSinceLastRun, onEditEvent, editEvents, defaultActiveTab, autoRotate3dViewerDisabled, showSchematicDebugGrid, showToggleFullScreen, defaultToFullScreen, }: PreviewContentProps) => react_jsx_runtime.JSX.Element;
90
+ declare const CircuitJsonPreview: ({ code, onRunClicked, errorMessage, errorStack, circuitJson, autoroutingGraphics, showRightHeaderContent, showCodeTab, codeTabContent, showJsonTab, showRenderLogTab, onActiveTabChange, renderLog, showImportAndFormatButtons, className, headerClassName, leftHeaderContent, readOnly, isStreaming, autoroutingLog, onReportAutoroutingLog, isRunningCode, hasCodeChangedSinceLastRun, onEditEvent, editEvents, defaultActiveTab, autoRotate3dViewerDisabled, showSchematicDebugGrid, showToggleFullScreen, defaultToFullScreen, activeEffectName, }: PreviewContentProps) => react_jsx_runtime.JSX.Element;
87
91
 
88
92
  interface BomTableProps {
89
93
  circuitJson: AnyCircuitElement[];
package/dist/preview.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  linkify,
9
9
  useOrderDialog,
10
10
  useOrderDialogCli
11
- } from "./chunk-AEWBBJRD.js";
11
+ } from "./chunk-7VN46VEY.js";
12
12
  export {
13
13
  BomTable,
14
14
  CadViewer,
package/dist/runner.js CHANGED
@@ -27,7 +27,7 @@ import {
27
27
  useOrderDialog,
28
28
  useOrderDialogCli,
29
29
  useRunFrameStore
30
- } from "./chunk-AEWBBJRD.js";
30
+ } from "./chunk-7VN46VEY.js";
31
31
 
32
32
  // lib/components/RunFrame/RunFrame.tsx
33
33
  import { createCircuitWebWorker } from "@tscircuit/eval/worker";
@@ -164,6 +164,11 @@ var RunFrame = (props) => {
164
164
  const lastRunCountTriggerRef = useRef2(0);
165
165
  const runMutex = useMutex();
166
166
  const [isRunning, setIsRunning] = useState(false);
167
+ const [dependenciesLoaded, setDependenciesLoaded] = useState(false);
168
+ const [activeAsyncEffects, setActiveAsyncEffects] = useState({});
169
+ const activeEffectName = Object.values(activeAsyncEffects).sort(
170
+ (a, b) => a.startTime - b.startTime
171
+ )[0]?.effectName;
167
172
  useEffect(() => {
168
173
  const handleKeyDown = (e) => {
169
174
  if ((e.ctrlKey || e.metaKey) && e.key === "Enter" && !isRunning) {
@@ -173,6 +178,29 @@ var RunFrame = (props) => {
173
178
  window.addEventListener("keydown", handleKeyDown);
174
179
  return () => window.removeEventListener("keydown", handleKeyDown);
175
180
  }, [isRunning]);
181
+ useEffect(() => {
182
+ let cancelled = false;
183
+ const load = async () => {
184
+ try {
185
+ if (!globalThis.runFrameWorker) {
186
+ const worker = await createCircuitWebWorker({
187
+ evalVersion: props.evalVersion ?? "latest",
188
+ webWorkerBlobUrl: props.evalWebWorkerBlobUrl,
189
+ verbose: true
190
+ });
191
+ if (cancelled) return;
192
+ globalThis.runFrameWorker = worker;
193
+ }
194
+ if (!cancelled) setDependenciesLoaded(true);
195
+ } catch (err) {
196
+ console.error("Failed to preload eval worker", err);
197
+ }
198
+ };
199
+ load();
200
+ return () => {
201
+ cancelled = true;
202
+ };
203
+ }, [props.evalVersion, props.evalWebWorkerBlobUrl]);
176
204
  const [renderLog, setRenderLog] = useState(null);
177
205
  const [autoroutingLog, setAutoroutingLog] = useState({});
178
206
  const [activeTab, setActiveTab] = useState(
@@ -220,6 +248,7 @@ var RunFrame = (props) => {
220
248
  debug("running render worker");
221
249
  setError(null);
222
250
  setRenderLog(null);
251
+ setActiveAsyncEffects({});
223
252
  const renderLog2 = { progress: 0 };
224
253
  let cancelled = false;
225
254
  cancelExecutionRef.current = () => {
@@ -252,6 +281,20 @@ var RunFrame = (props) => {
252
281
  const renderIds = /* @__PURE__ */ new Set();
253
282
  const startRenderTime = Date.now();
254
283
  let lastRenderLogSet = Date.now();
284
+ worker.on("asyncEffect:start", (event) => {
285
+ const id = `${event.phase}|${event.componentDisplayName ?? ""}|${event.effectName}`;
286
+ setActiveAsyncEffects((effects) => ({
287
+ ...effects,
288
+ [id]: { ...event, startTime: Date.now() }
289
+ }));
290
+ });
291
+ worker.on("asyncEffect:end", (event) => {
292
+ const id = `${event.phase}|${event.componentDisplayName ?? ""}|${event.effectName}`;
293
+ setActiveAsyncEffects((effects) => {
294
+ const { [id]: _removed, ...rest } = effects;
295
+ return rest;
296
+ });
297
+ });
255
298
  worker.on("autorouting:start", (event) => {
256
299
  setAutoroutingLog({
257
300
  ...autoroutingLog,
@@ -306,6 +349,7 @@ var RunFrame = (props) => {
306
349
  });
307
350
  if (!evalResult.success) {
308
351
  setIsRunning(false);
352
+ setActiveAsyncEffects({});
309
353
  return;
310
354
  }
311
355
  const $renderResult = worker.renderUntilSettled();
@@ -316,6 +360,7 @@ var RunFrame = (props) => {
316
360
  setError({ error: e.message, stack: e.stack });
317
361
  setRenderLog(null);
318
362
  setIsRunning(false);
363
+ setActiveAsyncEffects({});
319
364
  return null;
320
365
  });
321
366
  if (!circuitJson2) return;
@@ -340,6 +385,7 @@ var RunFrame = (props) => {
340
385
  setRenderLog({ ...renderLog2 });
341
386
  }
342
387
  setIsRunning(false);
388
+ setActiveAsyncEffects({});
343
389
  cancelExecutionRef.current = null;
344
390
  };
345
391
  runMutex.runWithMutex(runWorker);
@@ -416,11 +462,11 @@ var RunFrame = (props) => {
416
462
  incRunCountTrigger(1);
417
463
  },
418
464
  className: "rf-flex rf-items-center rf-gap-2 rf-px-4 rf-py-2 rf-bg-blue-600 hover:rf-bg-blue-700 rf-text-white rf-rounded-md disabled:rf-opacity-50 transition-colors duration-200",
419
- disabled: isRunning,
465
+ disabled: isRunning || !dependenciesLoaded,
420
466
  children: [
421
467
  "Run",
422
468
  " ",
423
- isRunning ? /* @__PURE__ */ jsx(Loader2, { className: "rf-w-3 rf-h-3 rf-animate-spin" }) : /* @__PURE__ */ jsx(Play, { className: "rf-w-3 rf-h-3" })
469
+ isRunning || !dependenciesLoaded ? /* @__PURE__ */ jsx(Loader2, { className: "rf-w-3 rf-h-3 rf-animate-spin" }) : /* @__PURE__ */ jsx(Play, { className: "rf-w-3 rf-h-3" })
424
470
  ]
425
471
  }
426
472
  ),
@@ -437,6 +483,7 @@ var RunFrame = (props) => {
437
483
  cancelExecutionRef.current = null;
438
484
  }
439
485
  runMutex.cancel();
486
+ setActiveAsyncEffects({});
440
487
  if (globalThis.runFrameWorker) {
441
488
  globalThis.runFrameWorker.kill();
442
489
  globalThis.runFrameWorker = null;
@@ -461,6 +508,7 @@ var RunFrame = (props) => {
461
508
  onActiveTabChange: setActiveTab,
462
509
  circuitJson,
463
510
  renderLog,
511
+ activeEffectName,
464
512
  isRunningCode: isRunning,
465
513
  errorMessage: error?.error,
466
514
  errorStack: error?.stack,