@tscircuit/runframe 0.0.185 → 0.0.187

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/runner.js CHANGED
@@ -1,7 +1,15 @@
1
1
  import {
2
2
  Button,
3
- CircuitJsonPreview
4
- } from "./chunk-FUPLP2UR.js";
3
+ CircuitJsonPreview,
4
+ DropdownMenu,
5
+ DropdownMenuContent,
6
+ DropdownMenuItem,
7
+ DropdownMenuPortal,
8
+ DropdownMenuSub,
9
+ DropdownMenuSubContent,
10
+ DropdownMenuSubTrigger,
11
+ DropdownMenuTrigger
12
+ } from "./chunk-TUAPVCCC.js";
5
13
 
6
14
  // lib/components/RunFrame/RunFrame.tsx
7
15
  import { createCircuitWebWorker } from "@tscircuit/eval";
@@ -597,7 +605,7 @@ var RunFrameWithApi = (props) => {
597
605
  );
598
606
  };
599
607
 
600
- // lib/components/RunFrameForCli/SaveToSnippetsButton.tsx
608
+ // lib/components/RunFrameForCli/LeftHeader.tsx
601
609
  import { useEffect as useEffect5, useMemo as useMemo4, useState as useState5 } from "react";
602
610
 
603
611
  // lib/components/RunFrameForCli/SelectSnippetDialog.tsx
@@ -702,15 +710,23 @@ var useEventHandler = (callback) => {
702
710
  }, [recentEvents, callback]);
703
711
  };
704
712
 
705
- // lib/components/RunFrameForCli/SaveToSnippetsButton.tsx
706
- import { CheckCircle2 } from "lucide-react";
707
- import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
708
- var SaveToSnippetsButton = () => {
713
+ // lib/components/RunFrameForCli/LeftHeader.tsx
714
+ import { AlertCircle, CheckCircle } from "lucide-react";
715
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
716
+ var availableExports = [
717
+ "json",
718
+ "svg",
719
+ "dsn",
720
+ "glb",
721
+ "csv",
722
+ "text",
723
+ "kicad_mod",
724
+ "kicad project"
725
+ ];
726
+ var RunframeCliLeftHeader = () => {
709
727
  const [snippetName, setSnippetName] = useState5(null);
710
728
  const [hasUnsavedChanges, setHasUnsavedChanges] = useState5(false);
711
729
  const [hasNeverBeenSaved, setHasNeverBeenSaved] = useState5(true);
712
- const pushEvent = useRunFrameStore((state) => state.pushEvent);
713
- const recentEvents = useRunFrameStore((state) => state.recentEvents);
714
730
  const [isSaving, setIsSaving] = useState5(false);
715
731
  const [requestToSaveSentAt, setRequestToSaveSentAt] = useState5(
716
732
  null
@@ -719,6 +735,13 @@ var SaveToSnippetsButton = () => {
719
735
  null
720
736
  );
721
737
  const [isSelectSnippetDialogOpen, setIsSelectSnippetDialogOpen] = useState5(false);
738
+ const [notificationMessage, setNotificationMessage] = useState5(
739
+ null
740
+ );
741
+ const [isError, setIsError] = useState5(false);
742
+ const [isExporting, setisExporting] = useState5(false);
743
+ const pushEvent = useRunFrameStore((state) => state.pushEvent);
744
+ const recentEvents = useRunFrameStore((state) => state.recentEvents);
722
745
  const firstRenderTime = useMemo4(() => Date.now(), []);
723
746
  useEventHandler((event) => {
724
747
  if (new Date(event.created_at).valueOf() < firstRenderTime + 500) return;
@@ -729,12 +752,23 @@ var SaveToSnippetsButton = () => {
729
752
  if (event.event_type === "SNIPPET_SAVED") {
730
753
  setHasUnsavedChanges(false);
731
754
  setHasNeverBeenSaved(false);
755
+ setNotificationMessage("Snippet saved successfully.");
756
+ setIsError(false);
732
757
  return;
733
758
  }
759
+ if (event.event_type === "REQUEST_EXPORT") {
760
+ setisExporting(true);
761
+ setNotificationMessage("Export requested...");
762
+ setIsError(false);
763
+ }
764
+ if (event.event_type === "EXPORT_CREATED") {
765
+ setNotificationMessage(`Export created: ${event.exportFilePath}`);
766
+ setIsError(false);
767
+ setisExporting(false);
768
+ }
734
769
  });
735
770
  useEffect5(() => {
736
- if (!isSaving) return;
737
- if (requestToSaveSentAt === null) return;
771
+ if (!isSaving || requestToSaveSentAt === null) return;
738
772
  const eventsSinceRequestToSave = recentEvents.filter(
739
773
  (event) => new Date(event.created_at).valueOf() > requestToSaveSentAt
740
774
  );
@@ -747,6 +781,11 @@ var SaveToSnippetsButton = () => {
747
781
  if (saveFailedEvent) {
748
782
  setIsSaving(false);
749
783
  setRequestToSaveSentAt(null);
784
+ setNotificationMessage(
785
+ saveFailedEvent.message ?? "Failed to save snippet. See console for error."
786
+ );
787
+ console.error(saveFailedEvent.message);
788
+ setIsError(true);
750
789
  if (saveFailedEvent.error_code === "SNIPPET_UNSET" && saveFailedEvent.available_snippet_names) {
751
790
  setAvailableSnippets(saveFailedEvent.available_snippet_names);
752
791
  setIsSelectSnippetDialogOpen(true);
@@ -755,29 +794,60 @@ var SaveToSnippetsButton = () => {
755
794
  if (saveSuccessEvent) {
756
795
  setIsSaving(false);
757
796
  setRequestToSaveSentAt(null);
797
+ setNotificationMessage("Snippet saved successfully.");
798
+ setIsError(false);
758
799
  }
759
800
  }, [recentEvents, isSaving]);
760
- return /* @__PURE__ */ jsxs4(Fragment2, { children: [
761
- /* @__PURE__ */ jsxs4(
762
- "button",
763
- {
764
- type: "button",
765
- onClick: async () => {
766
- setIsSaving(true);
767
- setRequestToSaveSentAt(Date.now());
768
- await pushEvent({
769
- event_type: "REQUEST_TO_SAVE_SNIPPET",
770
- snippet_name: snippetName
771
- });
772
- },
773
- disabled: isSaving,
774
- className: `px-3 flex items-center text-sm py-1.5 rounded-md ${isSaving ? "cursor-not-allowed" : "bg-white border border-gray-300 font-medium text-gray-900 shadow-sm"}`,
775
- children: [
776
- isSaving ? "Saving..." : "Save to Snippets",
777
- isSaving || hasNeverBeenSaved ? null : /* @__PURE__ */ jsx4("span", { className: "rf-ml-1.5 rf-flex rf-items-center", children: hasUnsavedChanges ? /* @__PURE__ */ jsx4("div", { className: "rf-text-xs rf-bg-orange-400 rf-text-white rf-p-0.5 rf-px-1.5 rf-rounded", children: "unsaved changes" }) : /* @__PURE__ */ jsx4(CheckCircle2, { className: "rf-w-4 rf-h-4 rf-text-green-500" }) })
778
- ]
779
- }
780
- ),
801
+ const triggerSaveSnippet = async () => {
802
+ setIsSaving(true);
803
+ setRequestToSaveSentAt(Date.now());
804
+ setNotificationMessage(null);
805
+ setIsError(false);
806
+ await pushEvent({
807
+ event_type: "REQUEST_TO_SAVE_SNIPPET",
808
+ snippet_name: snippetName
809
+ });
810
+ };
811
+ return /* @__PURE__ */ jsxs4(DropdownMenu, { children: [
812
+ /* @__PURE__ */ jsx4(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx4("div", { className: "rf-whitespace-nowrap rf-p-2 rf-mx-1 rf-cursor-pointer rf-relative", children: "File" }) }),
813
+ /* @__PURE__ */ jsxs4(DropdownMenuContent, { className: "rf-text-sm", children: [
814
+ /* @__PURE__ */ jsx4(DropdownMenuItem, { onSelect: triggerSaveSnippet, disabled: isSaving, children: isSaving ? "Saving..." : "Push" }),
815
+ /* @__PURE__ */ jsxs4(DropdownMenuSub, { children: [
816
+ /* @__PURE__ */ jsx4(DropdownMenuSubTrigger, { className: "rf-text-sm", disabled: isExporting, children: isExporting ? "Exporting..." : "Export" }),
817
+ /* @__PURE__ */ jsx4(DropdownMenuPortal, { children: /* @__PURE__ */ jsx4(DropdownMenuSubContent, { children: availableExports.map((ext, i) => /* @__PURE__ */ jsx4(
818
+ DropdownMenuItem,
819
+ {
820
+ className: "rf-text-xs",
821
+ onSelect: () => {
822
+ if (!isExporting) {
823
+ pushEvent({
824
+ event_type: "REQUEST_EXPORT",
825
+ exportType: ext
826
+ });
827
+ setNotificationMessage(`Export requested: ${ext}`);
828
+ setIsError(false);
829
+ }
830
+ },
831
+ disabled: isExporting,
832
+ children: ext
833
+ },
834
+ i
835
+ )) }) })
836
+ ] })
837
+ ] }),
838
+ /* @__PURE__ */ jsx4("div", { className: "!rf-h-full rf-w-fit rf-grid rf-place-items-center rf-my-auto", children: /* @__PURE__ */ jsxs4("div", { className: "rf-flex rf-gap-4", children: [
839
+ hasUnsavedChanges || hasNeverBeenSaved && /* @__PURE__ */ jsx4("div", { className: "rf-text-xs rf-h-fit rf-bg-orange-400 rf-text-white rf-p-0.5 rf-px-1.5 rf-rounded", children: "Unsaved changes" }),
840
+ notificationMessage && /* @__PURE__ */ jsx4(
841
+ "div",
842
+ {
843
+ className: `rf-text-xs rf-mt-1 rf-flex rf-max-w-xl rf-break-words rf-text-center rf-h-full ${isError ? "rf-text-red-500" : "rf-text-green-500"}`,
844
+ children: /* @__PURE__ */ jsxs4("div", { className: "rf-flex rf-items-center", children: [
845
+ isError ? /* @__PURE__ */ jsx4(AlertCircle, { className: "rf-w-4 rf-h-4 rf-inline rf-mr-1" }) : /* @__PURE__ */ jsx4(CheckCircle, { className: "rf-w-4 rf-h-4 rf-inline rf-mr-1" }),
846
+ notificationMessage
847
+ ] })
848
+ }
849
+ )
850
+ ] }) }),
781
851
  /* @__PURE__ */ jsx4(
782
852
  SelectSnippetDialog,
783
853
  {
@@ -806,7 +876,7 @@ var RunFrameForCli = (props) => {
806
876
  RunFrameWithApi,
807
877
  {
808
878
  debug: props.debug,
809
- leftHeaderContent: /* @__PURE__ */ jsx5("div", { children: /* @__PURE__ */ jsx5(SaveToSnippetsButton, {}) })
879
+ leftHeaderContent: /* @__PURE__ */ jsx5("div", { className: "rf-flex", children: /* @__PURE__ */ jsx5(RunframeCliLeftHeader, {}) })
810
880
  }
811
881
  );
812
882
  };
@@ -814,5 +884,6 @@ export {
814
884
  CircuitJsonPreview,
815
885
  RunFrame,
816
886
  RunFrameForCli,
817
- RunFrameWithApi
887
+ RunFrameWithApi,
888
+ guessEntrypoint
818
889
  };