@loopstack/loopstack-studio 0.22.0 → 0.23.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.
Files changed (82) hide show
  1. package/dist/app/EnvironmentEmbedRoot.js +20 -18
  2. package/dist/components/feedback/ErrorBoundary.js +43 -0
  3. package/dist/components/{LoadingCentered.js → feedback/LoadingCentered.js} +1 -1
  4. package/dist/components/feedback/index.js +5 -0
  5. package/dist/components/index.js +6 -3
  6. package/dist/components/layout/MainLayout.js +32 -16
  7. package/dist/components/layout/StudioSidebar.js +165 -0
  8. package/dist/components/ui-widgets/widgets/SandboxRun.js +1 -0
  9. package/dist/features/code-explorer/CodeExplorer.js +6 -0
  10. package/dist/features/code-explorer/components/CodeExplorerTree.js +5 -0
  11. package/dist/features/code-explorer/components/CodeExplorerTreeNode.js +6 -0
  12. package/dist/features/code-explorer/components/FileContentViewer.js +1 -0
  13. package/dist/features/code-explorer/components/FileTabsBar.js +1 -1
  14. package/dist/features/code-explorer/index.js +4 -0
  15. package/dist/features/debug/components/ConfigFlowViewer.js +1 -1
  16. package/dist/features/debug/components/PipelineFlowViewer.js +1 -1
  17. package/dist/features/debug/index.js +3 -0
  18. package/dist/features/documents/DocumentRenderer.js +53 -0
  19. package/dist/features/{workbench → documents}/components/DocumentItem.js +1 -1
  20. package/dist/features/{workbench → documents}/components/DocumentMetadataPills.js +2 -2
  21. package/dist/features/{workbench/components → documents}/document-details/DocumentDetails.js +3 -3
  22. package/dist/features/{workbench/components → documents}/document-details/PromptDetails.js +3 -3
  23. package/dist/features/documents/index.js +4 -0
  24. package/dist/features/{workbench/components/document-renderer → documents/renderers}/AiMessage.js +5 -5
  25. package/dist/features/{workbench/components/document-renderer → documents/renderers}/DocumentDebugRenderer.js +1 -1
  26. package/dist/features/{workbench/components/document-renderer → documents/renderers}/DocumentFormRenderer.js +3 -3
  27. package/dist/features/{workbench/components/document-renderer → documents/renderers}/DocumentMessageRenderer.js +1 -1
  28. package/dist/features/{workbench/components/document-renderer → documents/renderers}/ErrorMessageRenderer.js +1 -1
  29. package/dist/features/{workbench/components/document-renderer → documents/renderers}/LinkMessageRenderer.js +1 -1
  30. package/dist/features/{workbench/components/document-renderer → documents/renderers}/MarkdownMessageRenderer.js +2 -2
  31. package/dist/features/{workbench/components/document-renderer → documents/renderers}/PlainMessageRenderer.js +1 -1
  32. package/dist/features/health/index.js +1 -0
  33. package/dist/features/workbench/NavigationItems.js +29 -29
  34. package/dist/features/workbench/Workbench.js +57 -69
  35. package/dist/features/workbench/WorkflowItem.js +63 -55
  36. package/dist/features/workbench/WorkflowList.js +52 -81
  37. package/dist/features/workbench/components/NewRunDialog.js +2 -1
  38. package/dist/features/workbench/components/WorkbenchFlowPanel.js +5 -4
  39. package/dist/features/workbench/components/WorkflowHistoryItem.js +11 -11
  40. package/dist/features/workbench/components/buttons/WorkflowButtons.js +49 -50
  41. package/dist/features/workbench/hooks/useWorkflowData.js +49 -0
  42. package/dist/features/workbench/hooks/useWorkflowListState.js +50 -0
  43. package/dist/features/workbench/index.js +8 -0
  44. package/dist/features/workbench/providers/WorkbenchLayoutProvider.js +2 -3
  45. package/dist/features/workspaces/components/CreateWorkspace.js +1 -1
  46. package/dist/features/workspaces/components/ExecutionTimeline.js +1 -1
  47. package/dist/features/workspaces/components/PipelineForm.js +1 -1
  48. package/dist/features/workspaces/index.js +3 -0
  49. package/dist/hooks/index.js +3 -2
  50. package/dist/hooks/query-keys.js +138 -0
  51. package/dist/hooks/useAuth.js +43 -42
  52. package/dist/hooks/useConfig.js +31 -35
  53. package/dist/hooks/useDashboard.js +9 -13
  54. package/dist/hooks/useDebounce.js +8 -17
  55. package/dist/hooks/useDocuments.js +4 -9
  56. package/dist/hooks/useFiles.js +31 -39
  57. package/dist/hooks/useNamespaces.js +2 -8
  58. package/dist/hooks/usePipelines.js +132 -155
  59. package/dist/hooks/useProcessor.js +11 -14
  60. package/dist/hooks/useWorkflows.js +40 -62
  61. package/dist/hooks/useWorkspaces.js +105 -110
  62. package/dist/index.d.ts +99 -3
  63. package/dist/index.js +14 -7
  64. package/dist/pages/DashboardPage.js +1 -1
  65. package/dist/pages/DebugWorkflowDetailsPage.js +2 -2
  66. package/dist/pages/EmbedWorkbenchPage.js +4 -3
  67. package/dist/pages/PipelineDebugPage.js +6 -5
  68. package/dist/pages/PreviewWorkbenchPage.js +121 -118
  69. package/dist/pages/RunsListPage.js +52 -24
  70. package/dist/pages/StudioLandingPage.js +1 -0
  71. package/dist/pages/WorkbenchPage.js +3 -2
  72. package/dist/pages/WorkspacePage.js +1 -1
  73. package/dist/providers/InvalidationEventsProvider.js +9 -11
  74. package/dist/providers/StudioProvider.js +2 -2
  75. package/dist/routing/LocalRouter.js +12 -8
  76. package/package.json +1 -1
  77. package/dist/features/workbench/components/DocumentRenderer.js +0 -54
  78. /package/dist/components/{content → feedback}/ErrorAlert.js +0 -0
  79. /package/dist/components/{snackbars → feedback}/ErrorSnackbar.js +0 -0
  80. /package/dist/components/{snackbars → feedback}/Snackbar.js +0 -0
  81. /package/dist/features/{workbench → documents}/components/DocumentList.js +0 -0
  82. /package/dist/features/{workbench/components/document-renderer → documents/renderers}/AiMessageContent.js +0 -0
@@ -1,20 +1,23 @@
1
- import { useFilterPipelines, usePipeline, usePipelineConfig } from "../hooks/usePipelines.js";
1
+ import { useStudio } from "../providers/StudioProvider.js";
2
+ import { useFilterPipelines, usePipeline, usePipelineConfigByName } from "../hooks/usePipelines.js";
2
3
  import { useWorkspace } from "../hooks/useWorkspaces.js";
3
- import { useFetchWorkflowsByPipeline } from "../hooks/useWorkflows.js";
4
4
  import { Button } from "../components/ui/button.js";
5
5
  import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../components/ui/collapsible.js";
6
6
  import { SidebarMenu, SidebarProvider } from "../components/ui/sidebar.js";
7
- import ErrorSnackbar_default from "../components/snackbars/ErrorSnackbar.js";
8
- import LoadingCentered_default from "../components/LoadingCentered.js";
7
+ import LoadingCentered_default from "../components/feedback/LoadingCentered.js";
8
+ import ErrorSnackbar_default from "../components/feedback/ErrorSnackbar.js";
9
9
  import { require_enums } from "../packages/contracts/dist/enums/index.js";
10
10
  import { ReactFlowProvider } from "../node_modules/@xyflow/react/dist/esm/index.js";
11
+ import { useFetchWorkflowsByPipeline } from "../hooks/useWorkflows.js";
12
+ import PipelineFlowViewer_default from "../features/debug/components/PipelineFlowViewer.js";
13
+ import "../features/debug/index.js";
11
14
  import WorkflowItem_default from "../features/workbench/WorkflowItem.js";
12
15
  import WorkflowButtons_default from "../features/workbench/components/buttons/WorkflowButtons.js";
13
16
  import { useNamespaceTree } from "../hooks/useNamespaceTree.js";
14
17
  import WorkbenchNavigation_default from "../features/workbench/WorkbenchNavigation.js";
15
18
  import PipelineHistoryList_default from "../features/workbench/components/PipelineHistoryList.js";
16
- import PipelineFlowViewer_default from "../features/debug/components/PipelineFlowViewer.js";
17
19
  import { NewRunDialog } from "../features/workbench/components/NewRunDialog.js";
20
+ import "../features/workbench/index.js";
18
21
  import { c } from "react/compiler-runtime";
19
22
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
20
23
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -46,113 +49,113 @@ function PreviewWorkbenchPage() {
46
49
  }), e[3] = t, e[4] = o), o;
47
50
  }
48
51
  function PreviewWorkbenchContent(e) {
49
- let o = c(57), { pipelineId: s, onNewRunSuccess: l } = e, u = useRef(null), [d, m] = useState("output"), [_, v] = useState(!1), y = usePipeline(s), S = useFetchWorkflowsByPipeline(s), w;
50
- o[0] === S.data ? w = o[1] : (w = S.data ?? [], o[0] = S.data, o[1] = w);
51
- let T = w, E = useRef(!1), ge = y.data?.workspaceId, D = useWorkspace(ge).data?.blockName, O = y.data?.blockName, k = usePipelineConfig(D, O), A, j;
52
- o[2] !== S.data || o[3] !== s ? (A = () => {
53
- !S.data || E.current || S.data.length > 0 && S.data.every(_temp) && window.parent !== window && (E.current = !0, window.parent.postMessage({
52
+ let t = c(57), { pipelineId: o, onNewRunSuccess: s } = e, l = useRef(null), [u, d] = useState("output"), [m, y] = useState(!1), b = usePipeline(o), x = useFetchWorkflowsByPipeline(o), C;
53
+ t[0] === x.data ? C = t[1] : (C = x.data ?? [], t[0] = x.data, t[1] = C);
54
+ let T = C, E = useRef(!1), D = b.data?.workspaceId, ge = useWorkspace(D).data?.blockName, _e = b.data?.blockName, O = usePipelineConfigByName(ge, _e), k, A;
55
+ t[2] !== x.data || t[3] !== o ? (k = () => {
56
+ !x.data || E.current || x.data.length > 0 && x.data.every(_temp) && window.parent !== window && (E.current = !0, window.parent.postMessage({
54
57
  type: EMBED_MESSAGE_TYPE,
55
- pipelineId: s
58
+ pipelineId: o
56
59
  }, window.location.origin));
57
- }, j = [S.data, s], o[2] = S.data, o[3] = s, o[4] = A, o[5] = j) : (A = o[4], j = o[5]), useEffect(A, j);
58
- let M, N;
59
- o[6] === s ? (M = o[7], N = o[8]) : (M = () => {
60
- if (window.parent === window || !u.current) return;
60
+ }, A = [x.data, o], t[2] = x.data, t[3] = o, t[4] = k, t[5] = A) : (k = t[4], A = t[5]), useEffect(k, A);
61
+ let j, M;
62
+ t[6] === o ? (j = t[7], M = t[8]) : (j = () => {
63
+ if (window.parent === window || !l.current) return;
61
64
  let e = new ResizeObserver(() => {
62
- if (!u.current) return;
65
+ if (!l.current) return;
63
66
  let e = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);
64
67
  window.parent.postMessage({
65
68
  type: EMBED_RESIZE_MESSAGE_TYPE,
66
- pipelineId: s,
69
+ pipelineId: o,
67
70
  height: e
68
71
  }, window.location.origin);
69
72
  });
70
- return e.observe(u.current), () => e.disconnect();
71
- }, N = [s], o[6] = s, o[7] = M, o[8] = N), useEffect(M, N);
72
- let P;
73
- o[9] === l ? P = o[10] : (P = (e) => {
74
- v(!1), l(e);
75
- }, o[9] = l, o[10] = P);
76
- let F = P, I = _temp2, L;
77
- o[11] === Symbol.for("react.memo_cache_sentinel") ? (L = {
73
+ return e.observe(l.current), () => e.disconnect();
74
+ }, M = [o], t[6] = o, t[7] = j, t[8] = M), useEffect(j, M);
75
+ let N;
76
+ t[9] === s ? N = t[10] : (N = (e) => {
77
+ y(!1), s(e);
78
+ }, t[9] = s, t[10] = N);
79
+ let P = N, F = _temp2, I;
80
+ t[11] === Symbol.for("react.memo_cache_sentinel") ? (I = {
78
81
  enableDebugMode: !1,
79
82
  showFullMessageHistory: !1
80
- }, o[11] = L) : L = o[11];
81
- let R = L, z;
82
- o[12] === Symbol.for("react.memo_cache_sentinel") ? (z = {
83
+ }, t[11] = I) : I = t[11];
84
+ let L = I, R;
85
+ t[12] === Symbol.for("react.memo_cache_sentinel") ? (R = {
83
86
  value: "output",
84
87
  label: "Output",
85
88
  icon: /* @__PURE__ */ jsx(ScrollText, { className: "h-3.5 w-3.5" })
86
- }, o[12] = z) : z = o[12];
87
- let B;
88
- o[13] === Symbol.for("react.memo_cache_sentinel") ? (B = {
89
+ }, t[12] = R) : R = t[12];
90
+ let z;
91
+ t[13] === Symbol.for("react.memo_cache_sentinel") ? (z = {
89
92
  value: "graph",
90
93
  label: "Graph",
91
94
  icon: /* @__PURE__ */ jsx(Workflow, { className: "h-3.5 w-3.5" })
92
- }, o[13] = B) : B = o[13];
93
- let V;
94
- o[14] === Symbol.for("react.memo_cache_sentinel") ? (V = [
95
+ }, t[13] = z) : z = t[13];
96
+ let B;
97
+ t[14] === Symbol.for("react.memo_cache_sentinel") ? (B = [
98
+ R,
95
99
  z,
96
- B,
97
100
  {
98
101
  value: "run-log",
99
102
  label: "Run Log",
100
103
  icon: /* @__PURE__ */ jsx(ListOrdered, { className: "h-3.5 w-3.5" })
101
104
  }
102
- ], o[14] = V) : V = o[14];
103
- let _e = V, H;
104
- o[15] === d ? H = o[16] : (H = /* @__PURE__ */ jsx("div", {
105
+ ], t[14] = B) : B = t[14];
106
+ let V = B, H;
107
+ t[15] === u ? H = t[16] : (H = /* @__PURE__ */ jsx("div", {
105
108
  className: "bg-background flex items-center rounded-md border p-0.5",
106
- children: _e.map((e) => /* @__PURE__ */ jsxs("button", {
107
- onClick: () => m(e.value),
108
- className: `flex items-center gap-1.5 rounded-sm px-2.5 py-1 text-xs font-medium transition-colors ${d === e.value ? "bg-foreground text-background shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
109
+ children: V.map((e) => /* @__PURE__ */ jsxs("button", {
110
+ onClick: () => d(e.value),
111
+ className: `flex items-center gap-1.5 rounded-sm px-2.5 py-1 text-xs font-medium transition-colors ${u === e.value ? "bg-foreground text-background shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
109
112
  children: [e.icon, e.label]
110
113
  }, e.value))
111
- }), o[15] = d, o[16] = H);
114
+ }), t[15] = u, t[16] = H);
112
115
  let U;
113
- o[17] === Symbol.for("react.memo_cache_sentinel") ? (U = /* @__PURE__ */ jsxs(Button, {
116
+ t[17] === Symbol.for("react.memo_cache_sentinel") ? (U = /* @__PURE__ */ jsxs(Button, {
114
117
  variant: "outline",
115
118
  size: "sm",
116
119
  className: "h-7 gap-1.5",
117
- onClick: () => v(!0),
120
+ onClick: () => y(!0),
118
121
  children: [/* @__PURE__ */ jsx(Play, { className: "h-3 w-3" }), "New Run"]
119
- }), o[17] = U) : U = o[17];
122
+ }), t[17] = U) : U = t[17];
120
123
  let W;
121
- o[18] === H ? W = o[19] : (W = /* @__PURE__ */ jsxs("div", {
124
+ t[18] === H ? W = t[19] : (W = /* @__PURE__ */ jsxs("div", {
122
125
  className: "bg-muted/50 flex h-11 shrink-0 items-center justify-between border-b px-3",
123
126
  children: [H, U]
124
- }), o[18] = H, o[19] = W);
127
+ }), t[18] = H, t[19] = W);
125
128
  let G;
126
- o[20] === y.error ? G = o[21] : (G = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: y.error }), o[20] = y.error, o[21] = G);
129
+ t[20] === b.error ? G = t[21] : (G = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: b.error }), t[20] = b.error, t[21] = G);
127
130
  let K;
128
- o[22] === S.error ? K = o[23] : (K = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: S.error }), o[22] = S.error, o[23] = K);
131
+ t[22] === x.error ? K = t[23] : (K = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: x.error }), t[22] = x.error, t[23] = K);
129
132
  let q;
130
- o[24] !== d || o[25] !== y.data || o[26] !== y.isLoading || o[27] !== S.data || o[28] !== S.isLoading ? (q = d === "output" && /* @__PURE__ */ jsx("div", {
133
+ t[24] !== u || t[25] !== b.data || t[26] !== b.isLoading || t[27] !== x.data || t[28] !== x.isLoading ? (q = u === "output" && /* @__PURE__ */ jsx("div", {
131
134
  className: "px-4 py-3",
132
135
  children: /* @__PURE__ */ jsx(LoadingCentered_default, {
133
- loading: y.isLoading || S.isLoading,
134
- children: y.data && S.data ? S.data.map((e) => /* @__PURE__ */ jsx(EmbedWorkflowSection, {
136
+ loading: b.isLoading || x.isLoading,
137
+ children: b.data && x.data ? x.data.map((e) => /* @__PURE__ */ jsx(EmbedWorkflowSection, {
135
138
  workflow: e,
136
- pipeline: y.data,
137
- collapsible: S.data.length > 1,
139
+ pipeline: b.data,
140
+ collapsible: x.data.length > 1,
138
141
  children: /* @__PURE__ */ jsx(WorkflowItem_default, {
139
- pipeline: y.data,
142
+ pipeline: b.data,
140
143
  workflowId: e.id,
141
- scrollTo: I,
142
- settings: R
144
+ scrollTo: F,
145
+ settings: L
143
146
  })
144
147
  }, e.id)) : null
145
148
  })
146
- }), o[24] = d, o[25] = y.data, o[26] = y.isLoading, o[27] = S.data, o[28] = S.isLoading, o[29] = q) : q = o[29];
149
+ }), t[24] = u, t[25] = b.data, t[26] = b.isLoading, t[27] = x.data, t[28] = x.isLoading, t[29] = q) : q = t[29];
147
150
  let J;
148
- o[30] !== d || o[31] !== y.isLoading || o[32] !== k || o[33] !== S.isLoading || o[34] !== s || o[35] !== T ? (J = d === "graph" && /* @__PURE__ */ jsx("div", {
151
+ t[30] !== u || t[31] !== b.isLoading || t[32] !== O || t[33] !== x.isLoading || t[34] !== o || t[35] !== T ? (J = u === "graph" && /* @__PURE__ */ jsx("div", {
149
152
  className: "h-full",
150
153
  children: /* @__PURE__ */ jsx(LoadingCentered_default, {
151
- loading: y.isLoading || S.isLoading,
154
+ loading: b.isLoading || x.isLoading,
152
155
  children: T.length > 0 ? /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsx(PipelineFlowViewer_default, {
153
- pipelineId: s,
156
+ pipelineId: o,
154
157
  workflows: T,
155
- pipelineConfig: k.data
158
+ pipelineConfig: O.data
156
159
  }) }) : /* @__PURE__ */ jsx("div", {
157
160
  className: "text-muted-foreground flex h-full items-center justify-center",
158
161
  children: /* @__PURE__ */ jsx("p", {
@@ -161,19 +164,19 @@ function PreviewWorkbenchContent(e) {
161
164
  })
162
165
  })
163
166
  })
164
- }), o[30] = d, o[31] = y.isLoading, o[32] = k, o[33] = S.isLoading, o[34] = s, o[35] = T, o[36] = J) : J = o[36];
167
+ }), t[30] = u, t[31] = b.isLoading, t[32] = O, t[33] = x.isLoading, t[34] = o, t[35] = T, t[36] = J) : J = t[36];
165
168
  let Y;
166
- o[37] !== d || o[38] !== y.data ? (Y = d === "run-log" && /* @__PURE__ */ jsx("div", {
169
+ t[37] !== u || t[38] !== b.data ? (Y = u === "run-log" && /* @__PURE__ */ jsx("div", {
167
170
  className: "px-4",
168
- children: /* @__PURE__ */ jsx(PipelineHistoryList_default, { pipeline: y.data })
169
- }), o[37] = d, o[38] = y.data, o[39] = Y) : Y = o[39];
171
+ children: /* @__PURE__ */ jsx(PipelineHistoryList_default, { pipeline: b.data })
172
+ }), t[37] = u, t[38] = b.data, t[39] = Y) : Y = t[39];
170
173
  let X;
171
- o[40] !== d || o[41] !== s ? (X = d === "navigate" && /* @__PURE__ */ jsx("div", {
174
+ t[40] !== u || t[41] !== o ? (X = u === "navigate" && /* @__PURE__ */ jsx("div", {
172
175
  className: "px-4 py-2",
173
- children: /* @__PURE__ */ jsx(EmbedNavigationContent, { pipelineId: s })
174
- }), o[40] = d, o[41] = s, o[42] = X) : X = o[42];
176
+ children: /* @__PURE__ */ jsx(EmbedNavigationContent, { pipelineId: o })
177
+ }), t[40] = u, t[41] = o, t[42] = X) : X = t[42];
175
178
  let Z;
176
- o[43] !== G || o[44] !== K || o[45] !== q || o[46] !== J || o[47] !== Y || o[48] !== X ? (Z = /* @__PURE__ */ jsxs("div", {
179
+ t[43] !== G || t[44] !== K || t[45] !== q || t[46] !== J || t[47] !== Y || t[48] !== X ? (Z = /* @__PURE__ */ jsxs("div", {
177
180
  className: "flex-1 overflow-auto",
178
181
  children: [
179
182
  G,
@@ -183,23 +186,23 @@ function PreviewWorkbenchContent(e) {
183
186
  Y,
184
187
  X
185
188
  ]
186
- }), o[43] = G, o[44] = K, o[45] = q, o[46] = J, o[47] = Y, o[48] = X, o[49] = Z) : Z = o[49];
189
+ }), t[43] = G, t[44] = K, t[45] = q, t[46] = J, t[47] = Y, t[48] = X, t[49] = Z) : Z = t[49];
187
190
  let Q;
188
- o[50] !== F || o[51] !== _ ? (Q = /* @__PURE__ */ jsx(NewRunDialog, {
189
- open: _,
190
- onOpenChange: v,
191
- onSuccess: F
192
- }), o[50] = F, o[51] = _, o[52] = Q) : Q = o[52];
191
+ t[50] !== P || t[51] !== m ? (Q = /* @__PURE__ */ jsx(NewRunDialog, {
192
+ open: m,
193
+ onOpenChange: y,
194
+ onSuccess: P
195
+ }), t[50] = P, t[51] = m, t[52] = Q) : Q = t[52];
193
196
  let $;
194
- return o[53] !== W || o[54] !== Z || o[55] !== Q ? ($ = /* @__PURE__ */ jsxs("div", {
195
- ref: u,
197
+ return t[53] !== W || t[54] !== Z || t[55] !== Q ? ($ = /* @__PURE__ */ jsxs("div", {
198
+ ref: l,
196
199
  className: "flex h-screen flex-col overflow-hidden",
197
200
  children: [
198
201
  W,
199
202
  Z,
200
203
  Q
201
204
  ]
202
- }), o[53] = W, o[54] = Z, o[55] = Q, o[56] = $) : $ = o[56], $;
205
+ }), t[53] = W, t[54] = Z, t[55] = Q, t[56] = $) : $ = t[56], $;
203
206
  }
204
207
  function _temp2() {}
205
208
  function _temp(e) {
@@ -213,31 +216,31 @@ var STATUS_DOT_COLORS = {
213
216
  canceled: "bg-orange-500",
214
217
  pending: "bg-muted-foreground"
215
218
  };
216
- function PreviewEmptyState(t) {
217
- let n = c(23), { newRunDialogOpen: r, onNewRunDialogOpenChange: i, onNewRunSuccess: o } = t, s = useNavigate(), [l, u] = useState(3), d;
218
- n[0] === Symbol.for("react.memo_cache_sentinel") ? (d = { parentId: null }, n[0] = d) : d = n[0];
219
- let f = useFilterPipelines(void 0, d, "createdAt", "DESC", 0, l), p;
220
- n[1] === f.data?.data ? p = n[2] : (p = f.data?.data ?? [], n[1] = f.data?.data, n[2] = p);
221
- let m = p, h = f.data?.total ?? 0, g = m.length < h, _;
222
- n[3] === i ? _ = n[4] : (_ = () => i(!0), n[3] = i, n[4] = _);
223
- let v;
224
- n[5] === Symbol.for("react.memo_cache_sentinel") ? (v = /* @__PURE__ */ jsx(Play, { className: "h-3.5 w-3.5" }), n[5] = v) : v = n[5];
225
- let y;
226
- n[6] === _ ? y = n[7] : (y = /* @__PURE__ */ jsx("div", {
219
+ function PreviewEmptyState(n) {
220
+ let r = c(24), { newRunDialogOpen: i, onNewRunDialogOpenChange: o, onNewRunSuccess: s } = n, l = useNavigate(), { router: u } = useStudio(), [d, f] = useState(3), p;
221
+ r[0] === Symbol.for("react.memo_cache_sentinel") ? (p = { parentId: null }, r[0] = p) : p = r[0];
222
+ let m = useFilterPipelines(void 0, p, "createdAt", "DESC", 0, d), h;
223
+ r[1] === m.data?.data ? h = r[2] : (h = m.data?.data ?? [], r[1] = m.data?.data, r[2] = h);
224
+ let g = h, _ = m.data?.total ?? 0, v = g.length < _, y;
225
+ r[3] === o ? y = r[4] : (y = () => o(!0), r[3] = o, r[4] = y);
226
+ let b;
227
+ r[5] === Symbol.for("react.memo_cache_sentinel") ? (b = /* @__PURE__ */ jsx(Play, { className: "h-3.5 w-3.5" }), r[5] = b) : b = r[5];
228
+ let x;
229
+ r[6] === y ? x = r[7] : (x = /* @__PURE__ */ jsx("div", {
227
230
  className: "flex justify-center",
228
231
  children: /* @__PURE__ */ jsxs(Button, {
229
232
  variant: "secondary",
230
233
  size: "sm",
231
234
  className: "gap-1.5",
232
- onClick: _,
233
- children: [v, "New Run"]
235
+ onClick: y,
236
+ children: [b, "New Run"]
234
237
  })
235
- }), n[6] = _, n[7] = y);
236
- let b;
237
- n[8] !== f.isLoading || n[9] !== g || n[10] !== s || n[11] !== m ? (b = f.isLoading && m.length === 0 ? /* @__PURE__ */ jsx("div", {
238
+ }), r[6] = y, r[7] = x);
239
+ let S;
240
+ r[8] !== m.isLoading || r[9] !== v || r[10] !== l || r[11] !== g || r[12] !== u ? (S = m.isLoading && g.length === 0 ? /* @__PURE__ */ jsx("div", {
238
241
  className: "flex justify-center py-4",
239
242
  children: /* @__PURE__ */ jsx(Loader2, { className: "text-muted-foreground h-4 w-4 animate-spin" })
240
- }) : m.length > 0 ? /* @__PURE__ */ jsxs("div", { children: [
243
+ }) : g.length > 0 ? /* @__PURE__ */ jsxs("div", { children: [
241
244
  /* @__PURE__ */ jsx("p", {
242
245
  className: "text-muted-foreground mb-2 text-xs font-medium",
243
246
  children: "Recent"
@@ -246,34 +249,34 @@ function PreviewEmptyState(t) {
246
249
  className: "max-h-[280px] overflow-auto",
247
250
  children: /* @__PURE__ */ jsx("div", {
248
251
  className: "divide-border divide-y",
249
- children: m.map((e) => /* @__PURE__ */ jsx(RecentRunItem, {
252
+ children: g.map((e) => /* @__PURE__ */ jsx(RecentRunItem, {
250
253
  pipeline: e,
251
- onClick: () => void s(`/embed/preview/pipelines/${e.id}`)
254
+ onClick: () => void l(u.getPreviewPipeline(e.id))
252
255
  }, e.id))
253
256
  })
254
257
  }),
255
- g && /* @__PURE__ */ jsxs("button", {
258
+ v && /* @__PURE__ */ jsxs("button", {
256
259
  className: "text-muted-foreground hover:text-foreground mt-2 flex w-full items-center justify-center gap-1 py-1 text-xs transition-colors",
257
- onClick: () => u(_temp3),
260
+ onClick: () => f(_temp3),
258
261
  children: [/* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3" }), "Load more"]
259
262
  })
260
- ] }) : null, n[8] = f.isLoading, n[9] = g, n[10] = s, n[11] = m, n[12] = b) : b = n[12];
261
- let x;
262
- n[13] !== y || n[14] !== b ? (x = /* @__PURE__ */ jsxs("div", {
263
- className: "w-full max-w-sm space-y-6 px-4",
264
- children: [y, b]
265
- }), n[13] = y, n[14] = b, n[15] = x) : x = n[15];
266
- let S;
267
- n[16] !== r || n[17] !== i || n[18] !== o ? (S = /* @__PURE__ */ jsx(NewRunDialog, {
268
- open: r,
269
- onOpenChange: i,
270
- onSuccess: o
271
- }), n[16] = r, n[17] = i, n[18] = o, n[19] = S) : S = n[19];
263
+ ] }) : null, r[8] = m.isLoading, r[9] = v, r[10] = l, r[11] = g, r[12] = u, r[13] = S) : S = r[13];
272
264
  let C;
273
- return n[20] !== x || n[21] !== S ? (C = /* @__PURE__ */ jsxs("div", {
274
- className: "flex h-screen flex-col items-center justify-center",
265
+ r[14] !== x || r[15] !== S ? (C = /* @__PURE__ */ jsxs("div", {
266
+ className: "w-full max-w-sm space-y-6 px-4",
275
267
  children: [x, S]
276
- }), n[20] = x, n[21] = S, n[22] = C) : C = n[22], C;
268
+ }), r[14] = x, r[15] = S, r[16] = C) : C = r[16];
269
+ let w;
270
+ r[17] !== i || r[18] !== o || r[19] !== s ? (w = /* @__PURE__ */ jsx(NewRunDialog, {
271
+ open: i,
272
+ onOpenChange: o,
273
+ onSuccess: s
274
+ }), r[17] = i, r[18] = o, r[19] = s, r[20] = w) : w = r[20];
275
+ let T;
276
+ return r[21] !== C || r[22] !== w ? (T = /* @__PURE__ */ jsxs("div", {
277
+ className: "flex h-screen flex-col items-center justify-center",
278
+ children: [C, w]
279
+ }), r[21] = C, r[22] = w, r[23] = T) : T = r[23], T;
277
280
  }
278
281
  function _temp3(e) {
279
282
  return e + 5;
@@ -378,12 +381,12 @@ function EmbedWorkflowSection(e) {
378
381
  className: "py-1",
379
382
  children: a
380
383
  }) }), t[24] = a, t[25] = g);
381
- let v;
382
- return t[26] !== h || t[27] !== g ? (v = /* @__PURE__ */ jsxs(Collapsible, {
384
+ let _;
385
+ return t[26] !== h || t[27] !== g ? (_ = /* @__PURE__ */ jsxs(Collapsible, {
383
386
  defaultOpen: !0,
384
387
  className: "group/collapsible",
385
388
  children: [h, g]
386
- }), t[26] = h, t[27] = g, t[28] = v) : v = t[28], v;
389
+ }), t[26] = h, t[27] = g, t[28] = _) : _ = t[28], _;
387
390
  }
388
391
  function EmbedNavigationContent(e) {
389
392
  let t = c(4), { pipelineId: n } = e, r = useNamespaceTree(n);
@@ -1,36 +1,64 @@
1
1
  import { useStudio } from "../providers/StudioProvider.js";
2
+ import { Button } from "../components/ui/button.js";
2
3
  import MainLayout_default from "../components/layout/MainLayout.js";
4
+ import { NewRunDialog } from "../features/workbench/components/NewRunDialog.js";
3
5
  import Runs_default from "../features/runs/Runs.js";
4
6
  import { c } from "react/compiler-runtime";
7
+ import { useState } from "react";
5
8
  import { jsx, jsxs } from "react/jsx-runtime";
6
- import { Home } from "lucide-react";
9
+ import { Home, Play } from "lucide-react";
7
10
  function RunsListPage() {
8
- let s = c(12), { router: l } = useStudio(), u;
9
- s[0] === l ? u = s[1] : (u = l.getDashboard(), s[0] = l, s[1] = u);
10
- let d;
11
- s[2] === Symbol.for("react.memo_cache_sentinel") ? (d = /* @__PURE__ */ jsx(Home, { className: "h-4 w-4" }), s[2] = d) : d = s[2];
12
- let f;
13
- s[3] === u ? f = s[4] : (f = {
11
+ let f = c(19), { router: p } = useStudio(), [m, h] = useState(!1), g;
12
+ f[0] === p ? g = f[1] : (g = p.getDashboard(), f[0] = p, f[1] = g);
13
+ let _;
14
+ f[2] === Symbol.for("react.memo_cache_sentinel") ? (_ = /* @__PURE__ */ jsx(Home, { className: "h-4 w-4" }), f[2] = _) : _ = f[2];
15
+ let v;
16
+ f[3] === g ? v = f[4] : (v = {
14
17
  label: "Dashboard",
15
- href: u,
16
- icon: d
17
- }, s[3] = u, s[4] = f);
18
- let p;
19
- s[5] === Symbol.for("react.memo_cache_sentinel") ? (p = {
18
+ href: g,
19
+ icon: _
20
+ }, f[3] = g, f[4] = v);
21
+ let y;
22
+ f[5] === Symbol.for("react.memo_cache_sentinel") ? (y = {
20
23
  label: "Runs",
21
24
  current: !0
22
- }, s[5] = p) : p = s[5];
23
- let m;
24
- s[6] === f ? m = s[7] : (m = [f, p], s[6] = f, s[7] = m);
25
- let h = m, g, _;
26
- s[8] === Symbol.for("react.memo_cache_sentinel") ? (g = /* @__PURE__ */ jsx("h1", {
27
- className: "mb-4 text-3xl font-bold tracking-tight",
25
+ }, f[5] = y) : y = f[5];
26
+ let b;
27
+ f[6] === v ? b = f[7] : (b = [v, y], f[6] = v, f[7] = b);
28
+ let x = b, S;
29
+ f[8] === Symbol.for("react.memo_cache_sentinel") ? (S = /* @__PURE__ */ jsx("h1", {
30
+ className: "text-3xl font-bold tracking-tight",
28
31
  children: "Runs"
29
- }), _ = /* @__PURE__ */ jsx(Runs_default, {}), s[8] = g, s[9] = _) : (g = s[8], _ = s[9]);
30
- let v;
31
- return s[10] === h ? v = s[11] : (v = /* @__PURE__ */ jsxs(MainLayout_default, {
32
- breadcrumbsData: h,
33
- children: [g, _]
34
- }), s[10] = h, s[11] = v), v;
32
+ }), f[8] = S) : S = f[8];
33
+ let C, w;
34
+ f[9] === Symbol.for("react.memo_cache_sentinel") ? (C = /* @__PURE__ */ jsxs("div", {
35
+ className: "mb-4 flex items-center justify-between",
36
+ children: [S, /* @__PURE__ */ jsxs(Button, {
37
+ variant: "default",
38
+ size: "sm",
39
+ className: "gap-1.5",
40
+ onClick: () => h(!0),
41
+ children: [/* @__PURE__ */ jsx(Play, { className: "h-3.5 w-3.5" }), "New Run"]
42
+ })]
43
+ }), w = /* @__PURE__ */ jsx(Runs_default, {}), f[9] = C, f[10] = w) : (C = f[9], w = f[10]);
44
+ let T;
45
+ f[11] === p ? T = f[12] : (T = (r) => {
46
+ h(!1), p.navigateToPipeline(r);
47
+ }, f[11] = p, f[12] = T);
48
+ let E;
49
+ f[13] !== m || f[14] !== T ? (E = /* @__PURE__ */ jsx(NewRunDialog, {
50
+ open: m,
51
+ onOpenChange: h,
52
+ onSuccess: T
53
+ }), f[13] = m, f[14] = T, f[15] = E) : E = f[15];
54
+ let D;
55
+ return f[16] !== x || f[17] !== E ? (D = /* @__PURE__ */ jsxs(MainLayout_default, {
56
+ breadcrumbsData: x,
57
+ children: [
58
+ C,
59
+ w,
60
+ E
61
+ ]
62
+ }), f[16] = x, f[17] = E, f[18] = D) : D = f[18], D;
35
63
  }
36
64
  export { RunsListPage as default };
@@ -2,6 +2,7 @@ import { useStudio } from "../providers/StudioProvider.js";
2
2
  import { useFilterPipelines } from "../hooks/usePipelines.js";
3
3
  import { Button } from "../components/ui/button.js";
4
4
  import { NewRunDialog } from "../features/workbench/components/NewRunDialog.js";
5
+ import "../features/workbench/index.js";
5
6
  import { c } from "react/compiler-runtime";
6
7
  import { useCallback, useState } from "react";
7
8
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1,9 +1,10 @@
1
1
  import { useStudio } from "../providers/StudioProvider.js";
2
2
  import { usePipeline } from "../hooks/usePipelines.js";
3
3
  import { useWorkspace } from "../hooks/useWorkspaces.js";
4
- import ErrorSnackbar_default from "../components/snackbars/ErrorSnackbar.js";
5
- import LoadingCentered_default from "../components/LoadingCentered.js";
4
+ import LoadingCentered_default from "../components/feedback/LoadingCentered.js";
5
+ import ErrorSnackbar_default from "../components/feedback/ErrorSnackbar.js";
6
6
  import Workbench from "../features/workbench/Workbench.js";
7
+ import "../features/workbench/index.js";
7
8
  import { requireParam } from "../lib/requireParam.js";
8
9
  import { c } from "react/compiler-runtime";
9
10
  import { useCallback, useMemo } from "react";
@@ -1,7 +1,7 @@
1
1
  import { useStudio } from "../providers/StudioProvider.js";
2
2
  import { useWorkspace } from "../hooks/useWorkspaces.js";
3
3
  import MainLayout_default from "../components/layout/MainLayout.js";
4
- import ErrorSnackbar_default from "../components/snackbars/ErrorSnackbar.js";
4
+ import ErrorSnackbar_default from "../components/feedback/ErrorSnackbar.js";
5
5
  import ExecutionTimeline_default from "../features/workspaces/components/ExecutionTimeline.js";
6
6
  import { c } from "react/compiler-runtime";
7
7
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -1,19 +1,17 @@
1
1
  import { __toESM } from "../_virtual/rolldown_runtime.js";
2
+ import { getDocumentsCacheKey, getNamespacesByPipelineCacheKey, getWorkflowCacheKey, getWorkflowsByPipelineCacheKey, getWorkflowsCacheKey } from "../hooks/query-keys.js";
2
3
  import { SseClientEvents } from "../events/sse-client-events.js";
3
4
  import { eventBus } from "../services/eventEmitter.js";
4
5
  import "../services/index.js";
5
6
  import { useStudio } from "./StudioProvider.js";
6
7
  import { require_debounce } from "../node_modules/lodash/debounce.js";
7
- import { getDocumentsCacheKey } from "../hooks/useDocuments.js";
8
- import { getNamespacesByPipelineCacheKey } from "../hooks/useNamespaces.js";
9
- import { getWorkflowCacheKey, getWorkflowsByPipelineCacheKey, getWorkflowsCacheKey } from "../hooks/useWorkflows.js";
10
8
  import { c } from "react/compiler-runtime";
11
9
  import { useEffect, useRef } from "react";
12
10
  import { QueryClient, useQueryClient } from "@tanstack/react-query";
13
11
  var import_debounce = /* @__PURE__ */ __toESM(require_debounce(), 1), DEBOUNCE_MS = 300;
14
- function createDebouncedInvalidator(e, u) {
12
+ function createDebouncedInvalidator(e, l) {
15
13
  return (0, import_debounce.default)(() => {
16
- e.invalidateQueries({ queryKey: u });
14
+ e.invalidateQueries({ queryKey: l });
17
15
  }, DEBOUNCE_MS);
18
16
  }
19
17
  function InvalidationEventsProvider() {
@@ -23,12 +21,12 @@ function InvalidationEventsProvider() {
23
21
  return e[1] !== f.id || e[2] !== g ? (b = () => {
24
22
  if (!f.id) return;
25
23
  let e = f.id, d = y.current, p = function(e) {
26
- let u = JSON.stringify(e);
27
- d.has(u) || d.set(u, createDebouncedInvalidator(g, e)), d.get(u)();
28
- }, m = eventBus.on(SseClientEvents.WORKFLOW_CREATED, (u) => {
29
- u.namespaceId && p(getWorkflowsCacheKey(e, u.namespaceId)), u.pipelineId && (p(getNamespacesByPipelineCacheKey(e, u.pipelineId)), p(getWorkflowsByPipelineCacheKey(e, u.pipelineId)));
30
- }), h = eventBus.on(SseClientEvents.WORKFLOW_UPDATED, (u) => {
31
- u.id && p(getWorkflowCacheKey(e, u.id)), u.namespaceId && p(getWorkflowsCacheKey(e, u.namespaceId)), u.pipelineId && (p(getNamespacesByPipelineCacheKey(e, u.pipelineId)), p(getWorkflowsByPipelineCacheKey(e, u.pipelineId)));
24
+ let l = JSON.stringify(e);
25
+ d.has(l) || d.set(l, createDebouncedInvalidator(g, e)), d.get(l)();
26
+ }, m = eventBus.on(SseClientEvents.WORKFLOW_CREATED, (l) => {
27
+ l.namespaceId && p(getWorkflowsCacheKey(e, l.namespaceId)), l.pipelineId && (p(getNamespacesByPipelineCacheKey(e, l.pipelineId)), p(getWorkflowsByPipelineCacheKey(e, l.pipelineId)));
28
+ }), h = eventBus.on(SseClientEvents.WORKFLOW_UPDATED, (l) => {
29
+ l.id && p(getWorkflowCacheKey(e, l.id)), l.namespaceId && p(getWorkflowsCacheKey(e, l.namespaceId)), l.pipelineId && (p(getNamespacesByPipelineCacheKey(e, l.pipelineId)), p(getWorkflowsByPipelineCacheKey(e, l.pipelineId)));
32
30
  }), _ = eventBus.on(SseClientEvents.DOCUMENT_CREATED, (u) => {
33
31
  u.workflowId && p(getDocumentsCacheKey(e, u.workflowId));
34
32
  });
@@ -17,5 +17,5 @@ const StudioProvider = (r) => {
17
17
  let e = useContext(StudioContext);
18
18
  if (!e) throw Error("useStudio must be used within StudioProvider");
19
19
  return e;
20
- };
21
- export { StudioProvider, useStudio };
20
+ }, useStudioOptional = () => useContext(StudioContext);
21
+ export { StudioProvider, useStudio, useStudioOptional };
@@ -3,14 +3,18 @@ import { useNavigate } from "react-router-dom";
3
3
  var LocalRouter = class {
4
4
  navigate;
5
5
  envId;
6
- constructor(e, t) {
7
- this.navigate = e, this.envId = t;
6
+ embedPrefix;
7
+ constructor(e, t, n = "/embed") {
8
+ this.navigate = e, this.envId = t, this.embedPrefix = n;
8
9
  }
9
10
  async navigateToHome() {
10
11
  await this.navigate("/");
11
12
  }
13
+ getEnvironmentInfo() {
14
+ return "/info";
15
+ }
12
16
  async navigateToEnvironmentInfo() {
13
- await this.navigate("/info");
17
+ await this.navigate(this.getEnvironmentInfo());
14
18
  }
15
19
  getRuns() {
16
20
  return "/runs";
@@ -64,10 +68,10 @@ var LocalRouter = class {
64
68
  await this.navigate(`/workspaces/${e}/pipelines/${t}/namespaces/${n}`);
65
69
  }
66
70
  getEmbedPipeline(e) {
67
- return `/embed/pipelines/${e}`;
71
+ return `${this.embedPrefix}/pipelines/${e}`;
68
72
  }
69
73
  getPreviewPipeline(e) {
70
- return `/embed/preview/pipelines/${e}`;
74
+ return `${this.embedPrefix}/preview/pipelines/${e}`;
71
75
  }
72
76
  getCurrentEnvironmentId() {
73
77
  return this.envId;
@@ -76,8 +80,8 @@ var LocalRouter = class {
76
80
  return "local";
77
81
  }
78
82
  };
79
- const useRouter = (r) => {
80
- let i = c(3), a = useNavigate(), o;
81
- return i[0] !== r || i[1] !== a ? (o = new LocalRouter(a, r), i[0] = r, i[1] = a, i[2] = o) : o = i[2], o;
83
+ const useRouter = (r, i) => {
84
+ let a = c(4), o = useNavigate(), s;
85
+ return a[0] !== i || a[1] !== r || a[2] !== o ? (s = new LocalRouter(o, r, i), a[0] = i, a[1] = r, a[2] = o, a[3] = s) : s = a[3], s;
82
86
  };
83
87
  export { LocalRouter, useRouter };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loopstack/loopstack-studio",
3
- "version": "0.22.0",
3
+ "version": "0.23.0",
4
4
  "repository": "loopstack-ai/loopstack-studio",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",