@sampleapp.ai/sdk 1.0.36 → 1.0.37
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/components/sandbox/Sandbox.js +5 -0
- package/dist/components/sandbox/api.js +3 -2
- package/dist/components/sandbox/guardian/guardian-component.js +7 -38
- package/dist/components/sandbox/guardian/guardian-playground.js +1 -1
- package/dist/components/sandbox/guardian/hooks/use-sandbox-url-loader.js +12 -10
- package/dist/components/sandbox/guardian/index.js +1 -1
- package/dist/components/sandbox/guardian/right-view/right-top-down-view.js +1 -1
- package/dist/components/sandbox/guardian/ui/markdown.js +2 -2
- package/dist/components/sandbox/guardian/utils.js +0 -18
- package/dist/components/sandbox/index.js +1 -1
- package/dist/components/sandbox/sandbox-home/SandboxHome.js +5 -0
- package/dist/index.d.ts +8 -40
- package/dist/index.es.js +830 -867
- package/dist/index.js +1 -1
- package/dist/lib/api-client.js +9 -26
- package/package.json +1 -1
- package/dist/components/guardian/app-layout-no-sidebar.js +0 -8
- package/dist/components/guardian/ask-ai-view.js +0 -249
- package/dist/components/guardian/code-focus-section.d.ts +0 -41
- package/dist/components/guardian/code-focus-section.js +0 -174
- package/dist/components/guardian/context/guardian-context.js +0 -94
- package/dist/components/guardian/context/vm-context.js +0 -28
- package/dist/components/guardian/default-guide-view.js +0 -34
- package/dist/components/guardian/demo/guardian-demo.js +0 -35
- package/dist/components/guardian/demo/left-view/toggle.js +0 -28
- package/dist/components/guardian/demo/left-view.js +0 -49
- package/dist/components/guardian/guardian-component.js +0 -79
- package/dist/components/guardian/guardian-demo.js +0 -35
- package/dist/components/guardian/guardian-home.d.ts +0 -4
- package/dist/components/guardian/guardian-home.js +0 -61
- package/dist/components/guardian/guardian-playground.js +0 -45
- package/dist/components/guardian/guardian-style-wrapper.js +0 -29
- package/dist/components/guardian/guardian-upload-spec.d.ts +0 -14
- package/dist/components/guardian/guardian-upload-spec.js +0 -160
- package/dist/components/guardian/header/glassmorphic-combobox.d.ts +0 -15
- package/dist/components/guardian/header/glassmorphic-combobox.js +0 -30
- package/dist/components/guardian/header.js +0 -61
- package/dist/components/guardian/hooks/use-frame-messages.js +0 -65
- package/dist/components/guardian/hooks/use-frame-params.js +0 -44
- package/dist/components/guardian/hooks/use-sandbox-url-loader.js +0 -101
- package/dist/components/guardian/ide/browser.js +0 -538
- package/dist/components/guardian/index.js +0 -8
- package/dist/components/guardian/layout/app-layout-no-sidebar.js +0 -8
- package/dist/components/guardian/layout/header/glassmorphic-combobox.js +0 -48
- package/dist/components/guardian/layout/header.js +0 -63
- package/dist/components/guardian/right-view/code-view.js +0 -56
- package/dist/components/guardian/right-view/pill-file-selector.js +0 -233
- package/dist/components/guardian/right-view/preview-control-bar.js +0 -25
- package/dist/components/guardian/right-view/right-panel-view.js +0 -38
- package/dist/components/guardian/right-view/right-top-down-view.js +0 -289
- package/dist/components/guardian/right-view/right-view.js +0 -28
- package/dist/components/guardian/right-view/simplified-editor.js +0 -234
- package/dist/components/guardian/types/ide-types.js +0 -162
- package/dist/components/guardian/types.js +0 -3
- package/dist/components/guardian/ui/ai-loader.js +0 -48
- package/dist/components/guardian/ui/badge.js +0 -24
- package/dist/components/guardian/ui/button.js +0 -45
- package/dist/components/guardian/ui/command.js +0 -63
- package/dist/components/guardian/ui/console-with-app.js +0 -17
- package/dist/components/guardian/ui/dialog.js +0 -57
- package/dist/components/guardian/ui/dropdown-menu.js +0 -82
- package/dist/components/guardian/ui/markdown.js +0 -57
- package/dist/components/guardian/ui/popover.js +0 -25
- package/dist/components/guardian/ui/tooltip.js +0 -25
- package/dist/components/guardian/utils.js +0 -88
- package/dist/components/guardian/zip-to-codebase.js +0 -246
- package/dist/components/guardian/zip-to-filetree.js +0 -284
- package/dist/components/sandbox/SandboxHome.js +0 -141
- package/dist/components/sandbox/guardian/guardian-demo.js +0 -35
- package/dist/components/sandbox/guardian/guardian-home.d.ts +0 -4
- package/dist/components/sandbox/guardian/guardian-home.js +0 -61
- package/dist/components/sandbox/guardian/guardian-upload-spec.d.ts +0 -14
- package/dist/components/sandbox/guardian/guardian-upload-spec.js +0 -160
- package/dist/components/sandbox/guardian/ui/theme-color-context.d.ts +0 -6
- package/dist/components/sandbox/sandbox-control-bar.js +0 -91
- package/dist/components/sandbox/sandbox-header.js +0 -52
- package/dist/components/sandbox/sandbox-left-panel.js +0 -248
- package/dist/components/sandbox/sandbox-loading.js +0 -48
- package/dist/components/sandbox/sandbox-right-panel.js +0 -247
- package/dist/components/sandbox.js +0 -32
- package/dist/lib/api-client.example.js +0 -60
- package/dist/lib/ssr-safe-decode-entity.js +0 -16
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import React, { createContext, useContext, useState, useCallback, } from "react";
|
|
3
|
-
import { CodeLanguage, } from "../types/ide-types";
|
|
4
|
-
const GuardianContext = createContext(undefined);
|
|
5
|
-
export function GuardianProvider({ children }) {
|
|
6
|
-
const [previewUrl, setPreviewUrlState] = useState("");
|
|
7
|
-
const [isBrowserMaximized, setIsBrowserMaximized] = useState(false);
|
|
8
|
-
const [currentView, setCurrentViewState] = useState("preview");
|
|
9
|
-
// Code state
|
|
10
|
-
const [code, setCode] = useState("");
|
|
11
|
-
const [language, setLanguage] = useState(CodeLanguage.TEXT);
|
|
12
|
-
const [activeFileName, setActiveFileName] = useState("");
|
|
13
|
-
const [activeFilePath, setActiveFilePath] = useState("");
|
|
14
|
-
const [activeLineNumber, setActiveLineNumber] = useState(undefined);
|
|
15
|
-
const [activeLineRange, setActiveLineRange] = useState(undefined);
|
|
16
|
-
const [isGeneratingCode, setIsGeneratingCode] = useState(false);
|
|
17
|
-
// Generated code and file tree
|
|
18
|
-
const [generatedCode, setGeneratedCodeState] = useState({});
|
|
19
|
-
const [fileTree, setFileTree] = useState({
|
|
20
|
-
name: "root",
|
|
21
|
-
children: {},
|
|
22
|
-
type: "folder",
|
|
23
|
-
metadata: {
|
|
24
|
-
response_type: "CodeOutput",
|
|
25
|
-
file_path: "",
|
|
26
|
-
code_file_name: "",
|
|
27
|
-
code_language: CodeLanguage.TEXT,
|
|
28
|
-
dependencies_to_install: [],
|
|
29
|
-
framework: null,
|
|
30
|
-
full_code: "",
|
|
31
|
-
},
|
|
32
|
-
});
|
|
33
|
-
// Dependencies and edited files
|
|
34
|
-
const [activeDependenciesToInstall, setActiveDependenciesToInstall] = useState([]);
|
|
35
|
-
const [filesEdited, setFilesEdited] = useState({});
|
|
36
|
-
const setPreviewUrl = useCallback((url) => {
|
|
37
|
-
setPreviewUrlState(url);
|
|
38
|
-
}, []);
|
|
39
|
-
const setIsBrowserMaximizedState = useCallback((maximized) => {
|
|
40
|
-
setIsBrowserMaximized(maximized);
|
|
41
|
-
}, []);
|
|
42
|
-
const setCurrentView = useCallback((view) => {
|
|
43
|
-
setCurrentViewState(view);
|
|
44
|
-
}, []);
|
|
45
|
-
const updateCode = useCallback((newCode) => {
|
|
46
|
-
setCode(newCode);
|
|
47
|
-
}, []);
|
|
48
|
-
const setGeneratedCode = useCallback((generatedCode) => {
|
|
49
|
-
if (typeof generatedCode === "function") {
|
|
50
|
-
setGeneratedCodeState((prev) => generatedCode(prev));
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
setGeneratedCodeState(generatedCode);
|
|
54
|
-
}
|
|
55
|
-
}, []);
|
|
56
|
-
const value = {
|
|
57
|
-
previewUrl,
|
|
58
|
-
setPreviewUrl,
|
|
59
|
-
isBrowserMaximized,
|
|
60
|
-
setIsBrowserMaximized: setIsBrowserMaximizedState,
|
|
61
|
-
currentView,
|
|
62
|
-
setCurrentView,
|
|
63
|
-
code,
|
|
64
|
-
updateCode,
|
|
65
|
-
language,
|
|
66
|
-
setLanguage,
|
|
67
|
-
activeFileName,
|
|
68
|
-
setActiveFileName,
|
|
69
|
-
activeFilePath,
|
|
70
|
-
setActiveFilePath,
|
|
71
|
-
activeLineNumber,
|
|
72
|
-
setActiveLineNumber,
|
|
73
|
-
activeLineRange,
|
|
74
|
-
setActiveLineRange,
|
|
75
|
-
isGeneratingCode,
|
|
76
|
-
setIsGeneratingCode,
|
|
77
|
-
generatedCode,
|
|
78
|
-
setGeneratedCode,
|
|
79
|
-
fileTree,
|
|
80
|
-
setFileTree,
|
|
81
|
-
activeDependenciesToInstall,
|
|
82
|
-
setActiveDependenciesToInstall,
|
|
83
|
-
filesEdited,
|
|
84
|
-
setFilesEdited,
|
|
85
|
-
};
|
|
86
|
-
return (React.createElement(GuardianContext.Provider, { value: value }, children));
|
|
87
|
-
}
|
|
88
|
-
export function useGuardianContext() {
|
|
89
|
-
const context = useContext(GuardianContext);
|
|
90
|
-
if (!context) {
|
|
91
|
-
throw new Error("useGuardianContext must be used within a GuardianProvider");
|
|
92
|
-
}
|
|
93
|
-
return context;
|
|
94
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import React, { createContext, useContext, useState } from "react";
|
|
3
|
-
const VmContext = createContext(undefined);
|
|
4
|
-
export const VmProvider = ({ children }) => {
|
|
5
|
-
const [vmUrlMap, setVmUrlMap] = useState({});
|
|
6
|
-
const setVmUrl = (uid, url) => {
|
|
7
|
-
setVmUrlMap((prev) => (Object.assign(Object.assign({}, prev), { [uid]: url })));
|
|
8
|
-
};
|
|
9
|
-
const getVmUrl = (uid) => {
|
|
10
|
-
const value = vmUrlMap[uid];
|
|
11
|
-
// Return undefined if it's an error marker
|
|
12
|
-
return value === "error" ? undefined : value;
|
|
13
|
-
};
|
|
14
|
-
const setVmError = (uid) => {
|
|
15
|
-
setVmUrlMap((prev) => (Object.assign(Object.assign({}, prev), { [uid]: "error" })));
|
|
16
|
-
};
|
|
17
|
-
const hasError = (uid) => {
|
|
18
|
-
return vmUrlMap[uid] === "error";
|
|
19
|
-
};
|
|
20
|
-
return (React.createElement(VmContext.Provider, { value: { vmUrlMap, setVmUrl, getVmUrl, setVmError, hasError } }, children));
|
|
21
|
-
};
|
|
22
|
-
export const useVmContext = () => {
|
|
23
|
-
const context = useContext(VmContext);
|
|
24
|
-
if (!context) {
|
|
25
|
-
throw new Error("useVmContext must be used within a VmProvider");
|
|
26
|
-
}
|
|
27
|
-
return context;
|
|
28
|
-
};
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import { Markdown } from "./ui/markdown";
|
|
4
|
-
export default function DefaultGuideView({ themeColor, }) {
|
|
5
|
-
return (React.createElement("div", { className: "h-full flex flex-col" },
|
|
6
|
-
React.createElement("div", { className: "flex-1 px-8 py-6" },
|
|
7
|
-
React.createElement(Markdown, { className: "text-gray-100", themeColor: themeColor }, `# Guardian Guide
|
|
8
|
-
|
|
9
|
-
Learn how to use Guardian to build and deploy your application with confidence.
|
|
10
|
-
|
|
11
|
-
## Getting Started
|
|
12
|
-
|
|
13
|
-
Guardian provides a comprehensive development environment with real-time preview, code editing, and AI assistance.
|
|
14
|
-
|
|
15
|
-
### Features
|
|
16
|
-
|
|
17
|
-
- **Live Preview**: See your changes instantly as you code
|
|
18
|
-
- **Code Editor**: Edit files directly in the browser
|
|
19
|
-
- **AI Assistant**: Get help with your code using the Ask AI feature
|
|
20
|
-
|
|
21
|
-
### Navigation
|
|
22
|
-
|
|
23
|
-
Use the tabs at the top to switch between:
|
|
24
|
-
- **Guide**: View this documentation
|
|
25
|
-
- **Ask AI**: Get AI-powered assistance with your code
|
|
26
|
-
|
|
27
|
-
### Code Editing
|
|
28
|
-
|
|
29
|
-
Select files from the file selector to view and edit them. The editor supports syntax highlighting and automatic formatting.
|
|
30
|
-
|
|
31
|
-
### Preview
|
|
32
|
-
|
|
33
|
-
The preview panel shows your running application. Use the reload button to refresh the preview when needed.`))));
|
|
34
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import React, { useEffect, useState, useCallback } from "react";
|
|
3
|
-
import ConsoleWithApp from "../ui/console-with-app";
|
|
4
|
-
import { useGuardianContext } from "../context/guardian-context";
|
|
5
|
-
import ConsoleWithGuide from "./left-view";
|
|
6
|
-
import RightView from "../right-view/right-view";
|
|
7
|
-
export default function GuardianDemo({ CustomConsole, GuideView, browserUrl, playgroundUid, useVm, codeZipFile, completeCodeZipFile, variant, themeColor, hasPreview, isFrame = false, isGuardian = false, }) {
|
|
8
|
-
const { isBrowserMaximized } = useGuardianContext();
|
|
9
|
-
const { setCurrentView } = useGuardianContext();
|
|
10
|
-
const [reloadCounter, setReloadCounter] = useState(0);
|
|
11
|
-
const [overlayStage, setOverlayStage] = useState("hidden");
|
|
12
|
-
const handleReloadPreview = useCallback(() => {
|
|
13
|
-
setReloadCounter((c) => c + 1);
|
|
14
|
-
}, []);
|
|
15
|
-
const handleStageChange = useCallback((stage) => {
|
|
16
|
-
setOverlayStage(stage);
|
|
17
|
-
if (stage === "rebuilding") {
|
|
18
|
-
// Simulate a 3-second rebuild then hide
|
|
19
|
-
setTimeout(() => setOverlayStage("hidden"), 3000);
|
|
20
|
-
}
|
|
21
|
-
}, []);
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
setCurrentView("preview");
|
|
24
|
-
}, [setCurrentView]);
|
|
25
|
-
// If isFrame, just return RightView directly
|
|
26
|
-
if (isFrame) {
|
|
27
|
-
return (React.createElement(RightView, { reloadCounter: reloadCounter, overlayStage: overlayStage, browserUrl: browserUrl, useVm: useVm, codeZipFile: codeZipFile, hasPreview: hasPreview, variant: variant, themeColor: themeColor, completeCodeZipFile: completeCodeZipFile, isGuardian: isGuardian }));
|
|
28
|
-
}
|
|
29
|
-
// If browser is maximized, render RightView at full size without the console
|
|
30
|
-
if (isBrowserMaximized && isGuardian) {
|
|
31
|
-
return (React.createElement("div", { className: "w-full h-full rounded-2xl border border-border overflow-hidden" },
|
|
32
|
-
React.createElement(RightView, { reloadCounter: reloadCounter, overlayStage: overlayStage, browserUrl: browserUrl, useVm: useVm, codeZipFile: codeZipFile, hasPreview: hasPreview, variant: variant, themeColor: themeColor, completeCodeZipFile: completeCodeZipFile, isGuardian: isGuardian, isBrowserMaximized: true })));
|
|
33
|
-
}
|
|
34
|
-
return (React.createElement(ConsoleWithApp, { containerClassName: "rounded-2xl border border-border", console: React.createElement(ConsoleWithGuide, { CustomConsole: CustomConsole, GuideView: GuideView, playgroundUid: playgroundUid, onReloadPreview: handleReloadPreview, onStageChange: handleStageChange, codeZipFile: codeZipFile, themeColor: themeColor }), app: React.createElement(RightView, { reloadCounter: reloadCounter, overlayStage: overlayStage, browserUrl: browserUrl, useVm: useVm, codeZipFile: codeZipFile, hasPreview: hasPreview, variant: variant, themeColor: themeColor, completeCodeZipFile: completeCodeZipFile, isGuardian: isGuardian }) }));
|
|
35
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import { motion } from "framer-motion";
|
|
4
|
-
import { cn } from "../../../../lib/utils";
|
|
5
|
-
export default function SlidingEditPreviewToggle({ playgroundUid, variant = "default", buttonClassName = "", tabs = [
|
|
6
|
-
{ id: "editor", label: "Edit" },
|
|
7
|
-
{ id: "preview", label: "Preview" },
|
|
8
|
-
], currentView, setCurrentView, }) {
|
|
9
|
-
// Outer div and button shape depending on variant
|
|
10
|
-
const rootClasses = variant === "pill"
|
|
11
|
-
? "relative inline-flex items-center bg-muted/30 rounded-full p-1 border border-border/50"
|
|
12
|
-
: "relative inline-flex items-center bg-muted/30 rounded-lg p-1";
|
|
13
|
-
const btnShape = variant === "pill" ? "rounded-full" : "rounded-md";
|
|
14
|
-
const highlightShape = variant === "pill" ? "rounded-full" : "rounded-md";
|
|
15
|
-
// Default button padding if none provided
|
|
16
|
-
const defaultButtonPadding = variant === "pill" ? "px-5 py-2" : "px-4 py-1.5";
|
|
17
|
-
return (React.createElement("div", { className: rootClasses }, tabs.map((tab) => (React.createElement("button", { key: tab.id, onClick: () => setCurrentView(tab.id), className: cn(`relative ${defaultButtonPadding} text-sm font-medium transition-colors duration-150 ${btnShape} ${currentView === tab.id
|
|
18
|
-
? "text-foreground"
|
|
19
|
-
: "text-muted-foreground hover:text-foreground/80"}`, buttonClassName), style: {
|
|
20
|
-
WebkitTapHighlightColor: "transparent",
|
|
21
|
-
} },
|
|
22
|
-
currentView === tab.id && (React.createElement(motion.div, { layoutId: "activeTabGuide", className: cn(`absolute inset-0 bg-neutral-200 dark:bg-neutral-700 ${highlightShape} shadow-sm border border-border/50`), initial: false, transition: {
|
|
23
|
-
type: "spring",
|
|
24
|
-
stiffness: 500,
|
|
25
|
-
damping: 30,
|
|
26
|
-
} })),
|
|
27
|
-
React.createElement("span", { className: "relative z-10" }, tab.label))))));
|
|
28
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import React, { useMemo, useState } from "react";
|
|
3
|
-
import SlidingConsoleGuideToggle from "./left-view/toggle";
|
|
4
|
-
import AskAiView from "../ask-ai-view";
|
|
5
|
-
import DefaultGuideView from "../default-guide-view";
|
|
6
|
-
import { Markdown } from "../ui/markdown";
|
|
7
|
-
export default function ConsoleWithGuide({ CustomConsole, GuideView, playgroundUid, onReloadPreview, onStageChange, codeZipFile, themeColor, }) {
|
|
8
|
-
const [currentView, setCurrentView] = useState("console");
|
|
9
|
-
const isConsoleView = useMemo(() => currentView === "console", [currentView]);
|
|
10
|
-
const isGuideView = useMemo(() => currentView === "guide", [currentView]);
|
|
11
|
-
const isChatView = useMemo(() => currentView === "chat", [currentView]);
|
|
12
|
-
const renderCustomConsole = () => {
|
|
13
|
-
if (typeof CustomConsole === "string") {
|
|
14
|
-
return (React.createElement("div", { className: "h-full flex flex-col" },
|
|
15
|
-
React.createElement("div", { className: "flex-1 px-8 py-6" },
|
|
16
|
-
React.createElement(Markdown, { className: "text-gray-100", themeColor: themeColor }, CustomConsole))));
|
|
17
|
-
}
|
|
18
|
-
const CustomConsoleComponent = CustomConsole;
|
|
19
|
-
return (React.createElement(CustomConsoleComponent, { onReloadPreview: onReloadPreview !== null && onReloadPreview !== void 0 ? onReloadPreview : (() => { }), onStageChange: onStageChange !== null && onStageChange !== void 0 ? onStageChange : (() => { }), themeColor: themeColor }));
|
|
20
|
-
};
|
|
21
|
-
// Determine which guide view to render
|
|
22
|
-
const renderGuideView = () => {
|
|
23
|
-
if (!GuideView) {
|
|
24
|
-
// If no GuideView provided, render default
|
|
25
|
-
return (React.createElement(DefaultGuideView, { onReloadPreview: onReloadPreview !== null && onReloadPreview !== void 0 ? onReloadPreview : (() => { }), onStageChange: onStageChange !== null && onStageChange !== void 0 ? onStageChange : (() => { }), themeColor: themeColor }));
|
|
26
|
-
}
|
|
27
|
-
// If GuideView is a string, render as markdown
|
|
28
|
-
if (typeof GuideView === "string") {
|
|
29
|
-
return (React.createElement("div", { className: "h-full flex flex-col" },
|
|
30
|
-
React.createElement("div", { className: "flex-1 px-8 py-6" },
|
|
31
|
-
React.createElement(Markdown, { className: "text-gray-100", themeColor: themeColor }, GuideView))));
|
|
32
|
-
}
|
|
33
|
-
// Otherwise, render as React component
|
|
34
|
-
const GuideComponent = GuideView;
|
|
35
|
-
return React.createElement(GuideComponent, null);
|
|
36
|
-
};
|
|
37
|
-
return (React.createElement("div", { className: "flex-1 min-h-0 relative" },
|
|
38
|
-
React.createElement("div", { className: "flex justify-center border-b border-border" },
|
|
39
|
-
React.createElement(SlidingConsoleGuideToggle, { playgroundUid: playgroundUid, variant: "pill", buttonClassName: "text-sm px-4 py-1", currentView: currentView, setCurrentView: setCurrentView, tabs: [
|
|
40
|
-
{ id: "console", label: "Guide" },
|
|
41
|
-
...(GuideView ? [{ id: "guide-og", label: "Guide OG" }] : []),
|
|
42
|
-
{ id: "chat", label: "Ask AI" },
|
|
43
|
-
] })),
|
|
44
|
-
React.createElement("div", { className: "h-[calc(100vh-9.5rem)] min-h-0 overflow-hidden" },
|
|
45
|
-
React.createElement("div", { className: "h-full min-h-0 overflow-y-auto" },
|
|
46
|
-
isConsoleView && renderCustomConsole(),
|
|
47
|
-
isGuideView && renderGuideView(),
|
|
48
|
-
isChatView && (React.createElement(AskAiView, { codeZipFile: codeZipFile, playgroundUid: playgroundUid, themeColor: themeColor }))))));
|
|
49
|
-
}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import Header from "./header";
|
|
3
|
-
import AppLayoutNoSidebar from "./app-layout-no-sidebar";
|
|
4
|
-
import GuardianDemo from "./demo/guardian-demo";
|
|
5
|
-
import React, { useEffect, useRef } from "react";
|
|
6
|
-
import { useGuardianContext } from "./context/guardian-context";
|
|
7
|
-
import { useSandboxUrlLoader } from "./hooks/use-sandbox-url-loader";
|
|
8
|
-
import { useFrameMessages } from "./hooks/use-frame-messages";
|
|
9
|
-
export default function GuardianComponent({ demoOptions, frameworkOptions, firstFrameworkByUseCase, currentFramework, currentUseCase, CustomConsole, GuideView, playgroundLogo, playgroundUid, browserUrl, useVm, sandboxUid, codeZipFile, consoleUrlConfigs, completeCodeZipFile, variant, themeColor, hasPreview = true, isFrame = false, }) {
|
|
10
|
-
const { previewUrl, setPreviewUrl } = useGuardianContext();
|
|
11
|
-
const { getSandboxUrl, loadSandboxUrl, preloadSandboxUrls } = useSandboxUrlLoader();
|
|
12
|
-
// Initialize postMessage listener for iframe communication
|
|
13
|
-
// This sends IFRAME_READY and listens for UPDATE_VIEW messages
|
|
14
|
-
useFrameMessages();
|
|
15
|
-
// Track which console configs we've preloaded to prevent duplicates
|
|
16
|
-
const preloadedConfigsRef = useRef("");
|
|
17
|
-
// Track which main sandbox we've loaded to prevent duplicates
|
|
18
|
-
const loadedSandboxRef = useRef("");
|
|
19
|
-
// Preload console URLs when component mounts
|
|
20
|
-
useEffect(() => {
|
|
21
|
-
if (consoleUrlConfigs && consoleUrlConfigs.length > 0) {
|
|
22
|
-
// Create a key from the configs to detect changes
|
|
23
|
-
const configKey = JSON.stringify(consoleUrlConfigs.map((c) => c.sandboxUid));
|
|
24
|
-
// Only preload if we haven't already preloaded these configs
|
|
25
|
-
if (preloadedConfigsRef.current !== configKey) {
|
|
26
|
-
preloadedConfigsRef.current = configKey;
|
|
27
|
-
preloadSandboxUrls(consoleUrlConfigs).catch((error) => {
|
|
28
|
-
console.error("Failed to preload console URLs:", error);
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
// Only re-run if consoleUrlConfigs changes (not when preloadSandboxUrls changes)
|
|
33
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
34
|
-
}, [consoleUrlConfigs]);
|
|
35
|
-
useEffect(() => {
|
|
36
|
-
// Create a key for this sandbox load
|
|
37
|
-
const sandboxKey = `${sandboxUid}-${browserUrl}-${useVm}`;
|
|
38
|
-
// Check if we've already initiated a load for this exact sandbox config
|
|
39
|
-
if (loadedSandboxRef.current === sandboxKey) {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
// Check if URL is already cached for this sandboxUid + browserUrl combination
|
|
43
|
-
const existingUrl = getSandboxUrl(sandboxUid, browserUrl);
|
|
44
|
-
if (existingUrl !== undefined) {
|
|
45
|
-
// Found cached URL for this exact combination, use it immediately
|
|
46
|
-
setPreviewUrl(existingUrl);
|
|
47
|
-
loadedSandboxRef.current = sandboxKey;
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
// Mark as loading to prevent duplicate requests
|
|
51
|
-
loadedSandboxRef.current = sandboxKey;
|
|
52
|
-
// Load the sandbox URL (will be cached by sandboxUid + browserUrl)
|
|
53
|
-
// This allows switching between different browserUrls and reverting back
|
|
54
|
-
// without losing the cached URLs
|
|
55
|
-
setPreviewUrl("");
|
|
56
|
-
loadSandboxUrl({
|
|
57
|
-
sandboxUid,
|
|
58
|
-
browserUrl,
|
|
59
|
-
useVm,
|
|
60
|
-
})
|
|
61
|
-
.then((url) => {
|
|
62
|
-
setPreviewUrl(url);
|
|
63
|
-
})
|
|
64
|
-
.catch((error) => {
|
|
65
|
-
console.error("Failed to load sandbox URL:", error);
|
|
66
|
-
// Keep preview URL empty on error
|
|
67
|
-
});
|
|
68
|
-
// Only re-run if the sandbox parameters change (not when functions change)
|
|
69
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
70
|
-
}, [sandboxUid, browserUrl, useVm]);
|
|
71
|
-
// If isFrame, just render GuardianDemo without the header/layout wrapper
|
|
72
|
-
if (isFrame) {
|
|
73
|
-
return (React.createElement("div", { className: "h-[100vh]" },
|
|
74
|
-
React.createElement(GuardianDemo, { CustomConsole: CustomConsole, GuideView: GuideView, browserUrl: previewUrl, playgroundUid: playgroundUid, useVm: useVm, codeZipFile: codeZipFile, completeCodeZipFile: completeCodeZipFile, variant: variant, themeColor: themeColor, hasPreview: hasPreview, isFrame: isFrame, isGuardian: true })));
|
|
75
|
-
}
|
|
76
|
-
return (React.createElement(AppLayoutNoSidebar, { header: React.createElement(Header, { demoOptions: demoOptions, frameworkOptions: frameworkOptions, currentFramework: currentFramework, currentUseCase: currentUseCase, playgroundLogo: playgroundLogo, firstFrameworkByUseCase: firstFrameworkByUseCase }) },
|
|
77
|
-
React.createElement("div", { className: "absolute inset-0 mt-24 px-4 pb-4" },
|
|
78
|
-
React.createElement(GuardianDemo, { CustomConsole: CustomConsole, GuideView: GuideView, browserUrl: previewUrl, playgroundUid: playgroundUid, useVm: useVm, codeZipFile: codeZipFile, completeCodeZipFile: completeCodeZipFile, variant: variant, themeColor: themeColor, hasPreview: hasPreview, isFrame: isFrame, isGuardian: true }))));
|
|
79
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import React, { useEffect, useState, useCallback } from "react";
|
|
3
|
-
import ConsoleWithApp from "./ui/console-with-app";
|
|
4
|
-
import { useGuardianContext } from "./context/guardian-context";
|
|
5
|
-
import ConsoleWithGuide from "./demo/left-view";
|
|
6
|
-
import RightView from "./right-view/right-view";
|
|
7
|
-
export default function GuardianDemo({ CustomConsole, GuideView, browserUrl, playgroundUid, useVm, codeZipFile, completeCodeZipFile, variant, themeColor, hasPreview, isFrame = false, isGuardian = false, }) {
|
|
8
|
-
const { isBrowserMaximized } = useGuardianContext();
|
|
9
|
-
const { setCurrentView } = useGuardianContext();
|
|
10
|
-
const [reloadCounter, setReloadCounter] = useState(0);
|
|
11
|
-
const [overlayStage, setOverlayStage] = useState("hidden");
|
|
12
|
-
const handleReloadPreview = useCallback(() => {
|
|
13
|
-
setReloadCounter((c) => c + 1);
|
|
14
|
-
}, []);
|
|
15
|
-
const handleStageChange = useCallback((stage) => {
|
|
16
|
-
setOverlayStage(stage);
|
|
17
|
-
if (stage === "rebuilding") {
|
|
18
|
-
// Simulate a 3-second rebuild then hide
|
|
19
|
-
setTimeout(() => setOverlayStage("hidden"), 3000);
|
|
20
|
-
}
|
|
21
|
-
}, []);
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
setCurrentView("preview");
|
|
24
|
-
}, [setCurrentView]);
|
|
25
|
-
// If isFrame, just return RightView directly
|
|
26
|
-
if (isFrame) {
|
|
27
|
-
return (React.createElement(RightView, { reloadCounter: reloadCounter, overlayStage: overlayStage, browserUrl: browserUrl, useVm: useVm, codeZipFile: codeZipFile, hasPreview: hasPreview, variant: variant, themeColor: themeColor, completeCodeZipFile: completeCodeZipFile, isGuardian: isGuardian }));
|
|
28
|
-
}
|
|
29
|
-
// If browser is maximized, render RightView at full size without the console
|
|
30
|
-
if (isBrowserMaximized && isGuardian) {
|
|
31
|
-
return (React.createElement("div", { className: "w-full h-full rounded-2xl border overflow-hidden" },
|
|
32
|
-
React.createElement(RightView, { reloadCounter: reloadCounter, overlayStage: overlayStage, browserUrl: browserUrl, useVm: useVm, codeZipFile: codeZipFile, hasPreview: hasPreview, variant: variant, themeColor: themeColor, completeCodeZipFile: completeCodeZipFile, isGuardian: isGuardian, isBrowserMaximized: true })));
|
|
33
|
-
}
|
|
34
|
-
return (React.createElement(ConsoleWithApp, { containerClassName: "rounded-2xl border", console: React.createElement(ConsoleWithGuide, { CustomConsole: CustomConsole, GuideView: GuideView, playgroundUid: playgroundUid, onReloadPreview: handleReloadPreview, onStageChange: handleStageChange, codeZipFile: codeZipFile, themeColor: themeColor }), app: React.createElement(RightView, { reloadCounter: reloadCounter, overlayStage: overlayStage, browserUrl: browserUrl, useVm: useVm, codeZipFile: codeZipFile, hasPreview: hasPreview, variant: variant, themeColor: themeColor, completeCodeZipFile: completeCodeZipFile, isGuardian: isGuardian }) }));
|
|
35
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import Link from "next/link";
|
|
3
|
-
import AppLayoutNoSidebar from "./app-layout-no-sidebar";
|
|
4
|
-
import { useSandboxUrlLoader } from "./hooks/use-sandbox-url-loader";
|
|
5
|
-
import { useEffect, useRef } from "react";
|
|
6
|
-
export default function GuardianHome({ nestedConfig, }) {
|
|
7
|
-
var _a, _b, _c;
|
|
8
|
-
const { preloadSandboxUrls } = useSandboxUrlLoader();
|
|
9
|
-
const hasPreloadedRef = useRef(false);
|
|
10
|
-
// Preload all sandbox URLs when the home page loads (only once)
|
|
11
|
-
useEffect(() => {
|
|
12
|
-
// Prevent multiple preload attempts
|
|
13
|
-
if (hasPreloadedRef.current) {
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
hasPreloadedRef.current = true;
|
|
17
|
-
// Extract all framework configs from nested structure
|
|
18
|
-
const configs = Object.values(nestedConfig).flatMap((uc) => Object.values(uc.frameworks).flatMap((fw) => {
|
|
19
|
-
// Include the main framework config
|
|
20
|
-
const mainConfig = {
|
|
21
|
-
sandboxUid: fw.sandboxUid,
|
|
22
|
-
browserUrl: fw.browserUrl,
|
|
23
|
-
useVm: fw.useVm,
|
|
24
|
-
};
|
|
25
|
-
// Include additional URLs from consoleUrlConfigs (urlsToPreload)
|
|
26
|
-
const additionalConfigs = fw.consoleUrlConfigs || [];
|
|
27
|
-
return [mainConfig, ...additionalConfigs];
|
|
28
|
-
}));
|
|
29
|
-
// Preload all URLs in the background
|
|
30
|
-
preloadSandboxUrls(configs).catch((error) => {
|
|
31
|
-
console.error("Failed to preload some sandbox URLs:", error);
|
|
32
|
-
});
|
|
33
|
-
}, [nestedConfig, preloadSandboxUrls]);
|
|
34
|
-
// Build unique use cases list with first framework for each
|
|
35
|
-
const uniqueUseCases = Object.entries(nestedConfig).map(([id, uc]) => {
|
|
36
|
-
const firstFramework = Object.keys(uc.frameworks)[0];
|
|
37
|
-
return {
|
|
38
|
-
id,
|
|
39
|
-
name: uc.name,
|
|
40
|
-
description: uc.description,
|
|
41
|
-
firstFramework,
|
|
42
|
-
};
|
|
43
|
-
});
|
|
44
|
-
// Get playground logo from the first framework of the first use case
|
|
45
|
-
const playgroundLogo = (_c = (_a = Object.values(nestedConfig)[0]) === null || _a === void 0 ? void 0 : _a.frameworks[Object.keys(((_b = Object.values(nestedConfig)[0]) === null || _b === void 0 ? void 0 : _b.frameworks) || {})[0]]) === null || _c === void 0 ? void 0 : _c.playgroundLogo;
|
|
46
|
-
return (React.createElement(AppLayoutNoSidebar, { header: React.createElement("div", { className: "flex items-center gap-3 ml-6" }, playgroundLogo) },
|
|
47
|
-
React.createElement("div", { className: "h-full flex flex-col" },
|
|
48
|
-
React.createElement("div", { className: "flex-1 px-6 py-6 space-y-8" },
|
|
49
|
-
React.createElement("div", { className: "space-y-3" },
|
|
50
|
-
React.createElement("div", { className: "text-xs font-medium text-gray-400 tracking-wider uppercase" }, "Examples"),
|
|
51
|
-
React.createElement("h1", { className: "text-2xl font-semibold text-gray-100" }, "Sample apps"),
|
|
52
|
-
React.createElement("p", { className: "text-sm text-gray-400" }, "Select a sample app to explore and interact with")),
|
|
53
|
-
React.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6" }, uniqueUseCases.map((useCase) => (React.createElement(Link, { href: `/${useCase.id}?framework=${useCase.firstFramework}`, key: useCase.id },
|
|
54
|
-
React.createElement("div", { className: "bg-[#1a1b23] rounded-lg border border-gray-800 p-6 flex flex-col justify-between min-h-[180px] hover:border-gray-700 transition-colors cursor-pointer" },
|
|
55
|
-
React.createElement("div", null,
|
|
56
|
-
React.createElement("div", { className: "flex items-center gap-3 mb-2" },
|
|
57
|
-
React.createElement("h2", { className: "font-semibold text-base text-gray-100" }, useCase.name)),
|
|
58
|
-
React.createElement("div", { className: "text-gray-400 text-sm mb-6" }, useCase.description)),
|
|
59
|
-
React.createElement("div", { className: "flex items-center gap-2" },
|
|
60
|
-
React.createElement("span", { className: "text-xs text-gray-500" }, "View app \u2192")))))))))));
|
|
61
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import GuardianComponent from "./guardian-component";
|
|
4
|
-
import { useFrameParams } from "./hooks/use-frame-params";
|
|
5
|
-
import { GuardianStyleWrapper } from "./guardian-style-wrapper";
|
|
6
|
-
/**
|
|
7
|
-
* Guardian Playground component with nested config structure.
|
|
8
|
-
* Expects config[useCaseId].frameworks[frameworkKey] structure.
|
|
9
|
-
*
|
|
10
|
-
* When isFrame=true, reads framework from URL params client-side.
|
|
11
|
-
*/
|
|
12
|
-
export default function GuardianPlayground({ nestedConfig, useCase, framework: serverFramework, isFrame = false, }) {
|
|
13
|
-
var _a, _b;
|
|
14
|
-
// When in frame mode, allow URL params to override framework
|
|
15
|
-
const frameParams = useFrameParams();
|
|
16
|
-
const framework = isFrame && frameParams.framework ? frameParams.framework : serverFramework;
|
|
17
|
-
const useCaseConfig = nestedConfig[useCase];
|
|
18
|
-
if (!useCaseConfig) {
|
|
19
|
-
return (React.createElement("div", { className: "flex items-center justify-center h-screen" },
|
|
20
|
-
React.createElement("p", { className: "text-red-500" },
|
|
21
|
-
"Use case \"",
|
|
22
|
-
useCase,
|
|
23
|
-
"\" not found")));
|
|
24
|
-
}
|
|
25
|
-
const frameworkConfig = useCaseConfig.frameworks[framework];
|
|
26
|
-
if (!frameworkConfig) {
|
|
27
|
-
return (React.createElement("div", { className: "flex items-center justify-center h-screen" },
|
|
28
|
-
React.createElement("p", { className: "text-red-500" },
|
|
29
|
-
"Framework \"",
|
|
30
|
-
framework,
|
|
31
|
-
"\" not found in use case \"",
|
|
32
|
-
useCase,
|
|
33
|
-
"\"")));
|
|
34
|
-
}
|
|
35
|
-
// Build a map of use case ID to first available framework key
|
|
36
|
-
const firstFrameworkByUseCase = {};
|
|
37
|
-
Object.entries(nestedConfig).forEach(([useCaseId, uc]) => {
|
|
38
|
-
const firstFrameworkKey = Object.keys(uc.frameworks)[0];
|
|
39
|
-
if (firstFrameworkKey) {
|
|
40
|
-
firstFrameworkByUseCase[useCaseId] = firstFrameworkKey;
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
return (React.createElement(GuardianStyleWrapper, null,
|
|
44
|
-
React.createElement(GuardianComponent, { demoOptions: frameworkConfig.demoOptions, frameworkOptions: frameworkConfig.frameworkOptions, firstFrameworkByUseCase: firstFrameworkByUseCase, currentFramework: frameworkConfig.currentFramework, CustomConsole: frameworkConfig.CustomConsole, GuideView: frameworkConfig.GuideView, playgroundUid: frameworkConfig.playgroundUid, browserUrl: (_a = frameParams.iframeUrl) !== null && _a !== void 0 ? _a : frameworkConfig.browserUrl, useVm: frameworkConfig.useVm, playgroundLogo: frameworkConfig.playgroundLogo, sandboxUid: frameworkConfig.sandboxUid, name: frameworkConfig.name, description: frameworkConfig.description, codeZipFile: frameworkConfig.codeZipFile, completeCodeZipFile: frameworkConfig.completeCodeZipFile, consoleUrlConfigs: frameworkConfig.consoleUrlConfigs, variant: frameworkConfig.variant, themeColor: frameworkConfig.themeColor, hasPreview: (_b = frameworkConfig.hasPreview) !== null && _b !== void 0 ? _b : true, currentUseCase: useCase, isFrame: isFrame })));
|
|
45
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import React, { useEffect, useState } from "react";
|
|
3
|
-
import { TAILWIND_CSS } from "../../lib/generated-css";
|
|
4
|
-
/**
|
|
5
|
-
* Style wrapper for Guardian components that injects Tailwind CSS
|
|
6
|
-
* into the document without using Shadow DOM (preserves React context)
|
|
7
|
-
*/
|
|
8
|
-
export const GuardianStyleWrapper = ({ children, }) => {
|
|
9
|
-
const [stylesInjected, setStylesInjected] = useState(false);
|
|
10
|
-
useEffect(() => {
|
|
11
|
-
// Check if styles are already injected
|
|
12
|
-
const existingStyle = document.getElementById("guardian-sdk-styles");
|
|
13
|
-
if (existingStyle) {
|
|
14
|
-
setStylesInjected(true);
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
// Inject styles into document head
|
|
18
|
-
const styleElement = document.createElement("style");
|
|
19
|
-
styleElement.id = "guardian-sdk-styles";
|
|
20
|
-
// Scope styles to guardian-sdk class to avoid conflicts
|
|
21
|
-
styleElement.textContent = TAILWIND_CSS;
|
|
22
|
-
document.head.appendChild(styleElement);
|
|
23
|
-
setStylesInjected(true);
|
|
24
|
-
return () => {
|
|
25
|
-
// Don't remove styles on unmount as other Guardian components might use them
|
|
26
|
-
};
|
|
27
|
-
}, []);
|
|
28
|
-
return (React.createElement("div", { className: "guardian-sdk-root", style: { width: "100%", height: "100%" } }, children));
|
|
29
|
-
};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
type UploadedFile = {
|
|
3
|
-
name: string;
|
|
4
|
-
size: number;
|
|
5
|
-
type: string;
|
|
6
|
-
content?: string;
|
|
7
|
-
};
|
|
8
|
-
type GuardianUploadSpecProps = {
|
|
9
|
-
onBack: () => void;
|
|
10
|
-
onContinue: (file: UploadedFile) => void;
|
|
11
|
-
isLoading?: boolean;
|
|
12
|
-
};
|
|
13
|
-
export default function GuardianUploadSpec({ onBack, onContinue, isLoading, }: GuardianUploadSpecProps): React.JSX.Element;
|
|
14
|
-
export {};
|