create-rakta-app 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +86 -65
- package/dist/index.js.map +5 -5
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1758,7 +1758,8 @@ var PROJECT_MODE_DISPLAY = {
|
|
|
1758
1758
|
};
|
|
1759
1759
|
|
|
1760
1760
|
// src/welcomeComponents.ts
|
|
1761
|
-
var COMPONENTS_MODAL_CODE = `import React
|
|
1761
|
+
var COMPONENTS_MODAL_CODE = `import type React from 'react';
|
|
1762
|
+
import { useState } from 'react';
|
|
1762
1763
|
import { LuX as X, LuCopy as Copy, LuCheck as Check, LuCode as Code, LuCpu as Cpu } from 'react-icons/lu';
|
|
1763
1764
|
import { motion } from 'motion/react';
|
|
1764
1765
|
// import { playJumpSound, playScoreSound } from '../utils/audio'; // Removed to prevent error if not exists
|
|
@@ -1768,11 +1769,14 @@ interface ComponentsModalProps {
|
|
|
1768
1769
|
onClose: () => void;
|
|
1769
1770
|
}
|
|
1770
1771
|
|
|
1772
|
+
type ComponentState = Record<string, string | number | boolean | undefined>;
|
|
1773
|
+
type SetComponentState = (state: ComponentState) => void;
|
|
1774
|
+
|
|
1771
1775
|
interface ComponentItem {
|
|
1772
1776
|
id: string;
|
|
1773
1777
|
name: string;
|
|
1774
1778
|
description: string;
|
|
1775
|
-
preview: (state:
|
|
1779
|
+
preview: (state: ComponentState, setState: SetComponentState) => React.ReactNode;
|
|
1776
1780
|
code: string;
|
|
1777
1781
|
}
|
|
1778
1782
|
|
|
@@ -1786,12 +1790,14 @@ const BRUTALIST_COMPONENTS: ComponentItem[] = [
|
|
|
1786
1790
|
</button>\`,
|
|
1787
1791
|
preview: (state, setState) => (
|
|
1788
1792
|
<button
|
|
1793
|
+
type="button"
|
|
1789
1794
|
onClick={() => {
|
|
1790
|
-
|
|
1795
|
+
const clickCount = typeof state.clickCount === 'number' ? state.clickCount : 0;
|
|
1796
|
+
setState({ ...state, clickCount: clickCount + 1 });
|
|
1791
1797
|
}}
|
|
1792
1798
|
className="bg-brand-pink hover:bg-white text-white hover:text-black px-6 py-3 font-mono text-xs font-bold uppercase transition-all duration-150 border border-transparent hover:border-black active:scale-95 shadow-[4px_4px_0px_0px_rgba(255,255,255,0.25)] cursor-pointer"
|
|
1793
1799
|
>
|
|
1794
|
-
TRIGGER PIPELINE ({state.clickCount
|
|
1800
|
+
TRIGGER PIPELINE ({typeof state.clickCount === 'number' ? state.clickCount : 0})
|
|
1795
1801
|
</button>
|
|
1796
1802
|
)
|
|
1797
1803
|
},
|
|
@@ -1803,7 +1809,7 @@ const BRUTALIST_COMPONENTS: ComponentItem[] = [
|
|
|
1803
1809
|
<span class="w-1.5 h-1.5 bg-emerald-500 rounded-full animate-ping"></span>
|
|
1804
1810
|
OPERATIONAL :: 100%
|
|
1805
1811
|
</div>\`,
|
|
1806
|
-
preview: (
|
|
1812
|
+
preview: (_state, _setState) => (
|
|
1807
1813
|
<div className="flex items-center gap-2 border border-emerald-500/30 bg-emerald-950/20 px-3 py-1.5 font-mono text-xs text-emerald-400">
|
|
1808
1814
|
<span className="relative flex h-2 w-2">
|
|
1809
1815
|
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"></span>
|
|
@@ -1828,6 +1834,7 @@ const BRUTALIST_COMPONENTS: ComponentItem[] = [
|
|
|
1828
1834
|
return (
|
|
1829
1835
|
<div className="flex items-center gap-4">
|
|
1830
1836
|
<button
|
|
1837
|
+
type="button"
|
|
1831
1838
|
onClick={handleToggle}
|
|
1832
1839
|
className={\`flex items-center border-2 border-white p-0.5 w-16 h-8 transition-colors cursor-pointer \${isChecked ? 'bg-brand-pink' : 'bg-zinc-900'}\`}
|
|
1833
1840
|
>
|
|
@@ -1848,7 +1855,7 @@ const BRUTALIST_COMPONENTS: ComponentItem[] = [
|
|
|
1848
1855
|
<input type="range" class="accent-rose-600 bg-zinc-800 h-2 w-full border border-zinc-700 appearance-none cursor-pointer" />
|
|
1849
1856
|
</div>\`,
|
|
1850
1857
|
preview: (state, setState) => {
|
|
1851
|
-
const value = state.sliderVal
|
|
1858
|
+
const value = typeof state.sliderVal === 'number' ? state.sliderVal : 60;
|
|
1852
1859
|
return (
|
|
1853
1860
|
<div className="w-full max-w-sm font-mono text-xs">
|
|
1854
1861
|
<div className="flex justify-between mb-2">
|
|
@@ -1860,7 +1867,7 @@ const BRUTALIST_COMPONENTS: ComponentItem[] = [
|
|
|
1860
1867
|
min="10"
|
|
1861
1868
|
max="200"
|
|
1862
1869
|
value={value}
|
|
1863
|
-
onChange={(e) => setState({ ...state, sliderVal: parseInt(e.target.value) })}
|
|
1870
|
+
onChange={(e) => setState({ ...state, sliderVal: parseInt(e.target.value, 10) })}
|
|
1864
1871
|
className="accent-brand-pink bg-zinc-900 h-2 w-full border border-zinc-700 appearance-none cursor-pointer"
|
|
1865
1872
|
/>
|
|
1866
1873
|
<div className="flex justify-between mt-1 text-[9px] text-gray-600">
|
|
@@ -1880,17 +1887,19 @@ const BRUTALIST_COMPONENTS: ComponentItem[] = [
|
|
|
1880
1887
|
<input type="text" placeholder="ENTER NODE NAME..." class="bg-black border border-zinc-700 focus:border-rose-600 text-white px-4 py-2 w-full outline-none" />
|
|
1881
1888
|
</div>\`,
|
|
1882
1889
|
preview: (state, setState) => {
|
|
1883
|
-
const text = state.inputValue
|
|
1890
|
+
const text = typeof state.inputValue === 'string' ? state.inputValue : '';
|
|
1884
1891
|
return (
|
|
1885
1892
|
<div className="w-full max-w-xs font-mono text-xs">
|
|
1886
|
-
<label className="block text-gray-500 uppercase mb-1.5">
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1893
|
+
<label className="block text-gray-500 uppercase mb-1.5">
|
|
1894
|
+
Node Configuration
|
|
1895
|
+
<input
|
|
1896
|
+
type="text"
|
|
1897
|
+
placeholder="ENTER NODE NAME..."
|
|
1898
|
+
value={text}
|
|
1899
|
+
onChange={(e) => setState({ ...state, inputValue: e.target.value })}
|
|
1900
|
+
className="mt-1.5 bg-black border border-zinc-700 focus:border-brand-pink text-white px-4 py-2 w-full outline-none"
|
|
1901
|
+
/>
|
|
1902
|
+
</label>
|
|
1894
1903
|
{text && (
|
|
1895
1904
|
<p className="text-[10px] text-brand-green mt-1">\u2713 Validating: {text.toUpperCase()}.local</p>
|
|
1896
1905
|
)}
|
|
@@ -1902,15 +1911,18 @@ const BRUTALIST_COMPONENTS: ComponentItem[] = [
|
|
|
1902
1911
|
|
|
1903
1912
|
export default function ComponentsModal({ isOpen, onClose }: ComponentsModalProps) {
|
|
1904
1913
|
const [activeCompId, setActiveCompId] = useState('button');
|
|
1905
|
-
const [componentStates, setComponentStates] = useState<Record<string,
|
|
1914
|
+
const [componentStates, setComponentStates] = useState<Record<string, ComponentState>>({});
|
|
1906
1915
|
const [copiedId, setCopiedId] = useState<string | null>(null);
|
|
1907
1916
|
|
|
1908
1917
|
if (!isOpen) return null;
|
|
1909
1918
|
|
|
1910
|
-
const
|
|
1919
|
+
const fallbackComponent = BRUTALIST_COMPONENTS[0];
|
|
1920
|
+
if (!fallbackComponent) return null;
|
|
1921
|
+
|
|
1922
|
+
const activeComp = BRUTALIST_COMPONENTS.find(c => c.id === activeCompId) ?? fallbackComponent;
|
|
1911
1923
|
const activeState = componentStates[activeCompId] || {};
|
|
1912
1924
|
|
|
1913
|
-
const handleSetState = (newState:
|
|
1925
|
+
const handleSetState = (newState: ComponentState) => {
|
|
1914
1926
|
setComponentStates({
|
|
1915
1927
|
...componentStates,
|
|
1916
1928
|
[activeCompId]: newState
|
|
@@ -1940,6 +1952,7 @@ export default function ComponentsModal({ isOpen, onClose }: ComponentsModalProp
|
|
|
1940
1952
|
</h2>
|
|
1941
1953
|
</div>
|
|
1942
1954
|
<button
|
|
1955
|
+
type="button"
|
|
1943
1956
|
onClick={onClose}
|
|
1944
1957
|
className="p-2 border border-white hover:bg-rose-500 hover:text-white transition-colors cursor-pointer"
|
|
1945
1958
|
>
|
|
@@ -1953,6 +1966,7 @@ export default function ComponentsModal({ isOpen, onClose }: ComponentsModalProp
|
|
|
1953
1966
|
const isSelected = comp.id === activeCompId;
|
|
1954
1967
|
return (
|
|
1955
1968
|
<button
|
|
1969
|
+
type="button"
|
|
1956
1970
|
key={comp.id}
|
|
1957
1971
|
onClick={() => setActiveCompId(comp.id)}
|
|
1958
1972
|
className={\`w-full text-left p-4 transition-colors font-mono text-xs uppercase cursor-pointer \${
|
|
@@ -1984,6 +1998,7 @@ export default function ComponentsModal({ isOpen, onClose }: ComponentsModalProp
|
|
|
1984
1998
|
<Code className="w-3.5 h-3.5" /> HTML/Tailwind Markup
|
|
1985
1999
|
</span>
|
|
1986
2000
|
<button
|
|
2001
|
+
type="button"
|
|
1987
2002
|
onClick={() => handleCopyCode(activeComp.code)}
|
|
1988
2003
|
className="flex items-center gap-1.5 text-[10px] font-mono text-rose-500 hover:text-white transition-colors cursor-pointer"
|
|
1989
2004
|
>
|
|
@@ -2009,9 +2024,7 @@ export default function ComponentsModal({ isOpen, onClose }: ComponentsModalProp
|
|
|
2009
2024
|
);
|
|
2010
2025
|
}
|
|
2011
2026
|
`;
|
|
2012
|
-
var CORAL_OBSTACLE_CODE = `
|
|
2013
|
-
|
|
2014
|
-
interface CoralObstacleProps {
|
|
2027
|
+
var CORAL_OBSTACLE_CODE = `interface CoralObstacleProps {
|
|
2015
2028
|
position: 'TOP' | 'BOTTOM';
|
|
2016
2029
|
height: number;
|
|
2017
2030
|
width?: number;
|
|
@@ -2028,14 +2041,16 @@ export default function CoralObstacle({
|
|
|
2028
2041
|
variant = 0,
|
|
2029
2042
|
scaleX = 1
|
|
2030
2043
|
}: CoralObstacleProps) {
|
|
2044
|
+
const defaultPalette = { primary: '#f43f5e', secondary: '#fda4af', shadow: '#9f1239', polyps: '#ffe4e6', name: 'rose' };
|
|
2031
2045
|
const palettes = [
|
|
2032
|
-
|
|
2046
|
+
defaultPalette,
|
|
2033
2047
|
{ primary: '#06b6d4', secondary: '#67e8f9', shadow: '#155e75', polyps: '#ecfeff', name: 'cyan' },
|
|
2034
2048
|
{ primary: '#a855f7', secondary: '#d8b4fe', shadow: '#581c87', polyps: '#faf5ff', name: 'amethyst' },
|
|
2035
2049
|
{ primary: '#f59e0b', secondary: '#fde047', shadow: '#78350f', polyps: '#fefce8', name: 'amber' },
|
|
2036
2050
|
{ primary: '#10b981', secondary: '#6ee7b7', shadow: '#065f46', polyps: '#e6fffa', name: 'emerald' },
|
|
2037
2051
|
];
|
|
2038
|
-
const palette = palettes[paletteIndex % palettes.length]
|
|
2052
|
+
const palette = palettes[paletteIndex % palettes.length] ?? defaultPalette;
|
|
2053
|
+
const coralId = \`coralGrad-\${palette.name}-\${variant}\`;
|
|
2039
2054
|
|
|
2040
2055
|
return (
|
|
2041
2056
|
<div
|
|
@@ -2043,12 +2058,14 @@ export default function CoralObstacle({
|
|
|
2043
2058
|
style={{ height: \`\${height}px\`, width: \`\${width}px\`, transform: \`scaleX(\${scaleX})\` }}
|
|
2044
2059
|
>
|
|
2045
2060
|
<svg
|
|
2061
|
+
aria-hidden="true"
|
|
2062
|
+
focusable="false"
|
|
2046
2063
|
viewBox="0 0 80 120"
|
|
2047
2064
|
className="w-full h-full drop-shadow-[0_6px_14px_rgba(0,0,0,0.7)]"
|
|
2048
2065
|
preserveAspectRatio="none"
|
|
2049
2066
|
>
|
|
2050
2067
|
<defs>
|
|
2051
|
-
<linearGradient id={
|
|
2068
|
+
<linearGradient id={coralId} x1="0%" y1="0%" x2="100%" y2="100%">
|
|
2052
2069
|
<stop offset="0%" stopColor={palette.secondary} />
|
|
2053
2070
|
<stop offset="50%" stopColor={palette.primary} />
|
|
2054
2071
|
<stop offset="100%" stopColor={palette.shadow} />
|
|
@@ -2056,16 +2073,16 @@ export default function CoralObstacle({
|
|
|
2056
2073
|
</defs>
|
|
2057
2074
|
|
|
2058
2075
|
<g transform={position === 'TOP' ? 'scale(1, -1) translate(0, -120)' : undefined}>
|
|
2059
|
-
<path d="M 40 120 C 35 90, 20 80, 24 55 C 28 30, 15 20, 22 10 C 29 0, 37 15, 35 30 C 33 45, 42 55, 40 75 C 38 95, 42 110, 40 120 Z" fill={\`url(
|
|
2060
|
-
<path d="M 40 120 C 45 95, 55 85, 52 65 C 49 45, 62 35, 58 20 C 54 5, 46 12, 48 25 C 50 38, 42 50, 44 70 C 46 90, 42 105, 40 120 Z" fill={\`url(
|
|
2076
|
+
<path d="M 40 120 C 35 90, 20 80, 24 55 C 28 30, 15 20, 22 10 C 29 0, 37 15, 35 30 C 33 45, 42 55, 40 75 C 38 95, 42 110, 40 120 Z" fill={\`url(#\${coralId})\`} />
|
|
2077
|
+
<path d="M 40 120 C 45 95, 55 85, 52 65 C 49 45, 62 35, 58 20 C 54 5, 46 12, 48 25 C 50 38, 42 50, 44 70 C 46 90, 42 105, 40 120 Z" fill={\`url(#\${coralId})\`} />
|
|
2061
2078
|
</g>
|
|
2062
2079
|
</svg>
|
|
2063
2080
|
</div>
|
|
2064
2081
|
);
|
|
2065
2082
|
}
|
|
2066
2083
|
`;
|
|
2067
|
-
var DEPLOY_MODAL_CODE = `import
|
|
2068
|
-
import { LuX as X, LuPlay as Play,
|
|
2084
|
+
var DEPLOY_MODAL_CODE = `import { useState, useEffect, useRef } from 'react';
|
|
2085
|
+
import { LuX as X, LuPlay as Play, LuRotateCcw as RotateCcw, LuCloud as Cloud } from 'react-icons/lu';
|
|
2069
2086
|
import { motion } from 'motion/react';
|
|
2070
2087
|
|
|
2071
2088
|
interface DeployModalProps {
|
|
@@ -2095,7 +2112,7 @@ export default function DeployModal({ isOpen, onClose }: DeployModalProps) {
|
|
|
2095
2112
|
if (terminalEndRef.current) {
|
|
2096
2113
|
terminalEndRef.current.scrollIntoView({ behavior: 'smooth' });
|
|
2097
2114
|
}
|
|
2098
|
-
}
|
|
2115
|
+
});
|
|
2099
2116
|
|
|
2100
2117
|
if (!isOpen) return null;
|
|
2101
2118
|
|
|
@@ -2108,7 +2125,10 @@ export default function DeployModal({ isOpen, onClose }: DeployModalProps) {
|
|
|
2108
2125
|
|
|
2109
2126
|
const runStep = () => {
|
|
2110
2127
|
if (currentLogIndex < DEPLOY_LOGS.length) {
|
|
2111
|
-
|
|
2128
|
+
const nextLog = DEPLOY_LOGS[currentLogIndex];
|
|
2129
|
+
if (nextLog) {
|
|
2130
|
+
setLogs(prev => [...prev, nextLog]);
|
|
2131
|
+
}
|
|
2112
2132
|
setProgress(Math.round(((currentLogIndex + 1) / DEPLOY_LOGS.length) * 100));
|
|
2113
2133
|
currentLogIndex++;
|
|
2114
2134
|
setTimeout(runStep, Math.random() * 250 + 150);
|
|
@@ -2142,6 +2162,7 @@ export default function DeployModal({ isOpen, onClose }: DeployModalProps) {
|
|
|
2142
2162
|
</h2>
|
|
2143
2163
|
</div>
|
|
2144
2164
|
<button
|
|
2165
|
+
type="button"
|
|
2145
2166
|
onClick={onClose}
|
|
2146
2167
|
className="p-2 border border-white/30 hover:bg-rose-500 hover:text-white transition-colors cursor-pointer"
|
|
2147
2168
|
>
|
|
@@ -2160,12 +2181,12 @@ export default function DeployModal({ isOpen, onClose }: DeployModalProps) {
|
|
|
2160
2181
|
</div>
|
|
2161
2182
|
<div className="flex items-center gap-3">
|
|
2162
2183
|
{status === 'idle' && (
|
|
2163
|
-
<button onClick={startDeployment} className="bg-rose-500 hover:bg-white text-white hover:text-black px-6 py-2.5 font-mono text-xs font-bold uppercase transition-all duration-150 border border-transparent active:scale-95 flex items-center gap-2 cursor-pointer">
|
|
2184
|
+
<button type="button" onClick={startDeployment} className="bg-rose-500 hover:bg-white text-white hover:text-black px-6 py-2.5 font-mono text-xs font-bold uppercase transition-all duration-150 border border-transparent active:scale-95 flex items-center gap-2 cursor-pointer">
|
|
2164
2185
|
<Play className="w-4 h-4 fill-current" /> INITIATE LAUNCH
|
|
2165
2186
|
</button>
|
|
2166
2187
|
)}
|
|
2167
2188
|
{status === 'success' && (
|
|
2168
|
-
<button onClick={resetDeploy} className="border border-white hover:bg-white hover:text-black px-4 py-2.5 font-mono text-xs uppercase transition-all duration-150 flex items-center gap-1.5 cursor-pointer">
|
|
2189
|
+
<button type="button" onClick={resetDeploy} className="border border-white hover:bg-white hover:text-black px-4 py-2.5 font-mono text-xs uppercase transition-all duration-150 flex items-center gap-1.5 cursor-pointer">
|
|
2169
2190
|
<RotateCcw className="w-3.5 h-3.5" /> RE-BUILD PIPELINE
|
|
2170
2191
|
</button>
|
|
2171
2192
|
)}
|
|
@@ -2173,12 +2194,12 @@ export default function DeployModal({ isOpen, onClose }: DeployModalProps) {
|
|
|
2173
2194
|
</div>
|
|
2174
2195
|
|
|
2175
2196
|
<div className="flex-1 bg-black p-5 font-mono text-xs overflow-y-auto flex flex-col gap-2 select-text selection:bg-rose-500/30">
|
|
2176
|
-
{logs.map((log
|
|
2197
|
+
{logs.map((log) => {
|
|
2177
2198
|
let textColor = 'text-gray-400';
|
|
2178
2199
|
if (log.type === 'system') textColor = 'text-rose-500 font-bold border-b border-rose-500/20 pb-1 mb-2';
|
|
2179
2200
|
if (log.type === 'success') textColor = 'text-green-500 font-bold';
|
|
2180
2201
|
if (log.type === 'info') textColor = 'text-gray-300';
|
|
2181
|
-
return <div key={
|
|
2202
|
+
return <div key={\`\${log.type}-\${log.text}\`} className={\`leading-relaxed whitespace-pre-wrap \${textColor}\`}>{log.text}</div>;
|
|
2182
2203
|
})}
|
|
2183
2204
|
{status === 'idle' && <div className="text-gray-600 italic mt-4 text-center">Click 'INITIATE LAUNCH' to begin.</div>}
|
|
2184
2205
|
<div ref={terminalEndRef} />
|
|
@@ -2188,8 +2209,7 @@ export default function DeployModal({ isOpen, onClose }: DeployModalProps) {
|
|
|
2188
2209
|
);
|
|
2189
2210
|
}
|
|
2190
2211
|
`;
|
|
2191
|
-
var DOCS_MODAL_CODE = `import
|
|
2192
|
-
import { LuX as X, LuBook as Book, LuArrowRight as ArrowRight, LuSearch as Search } from 'react-icons/lu';
|
|
2212
|
+
var DOCS_MODAL_CODE = `import { LuX as X, LuBook as Book } from 'react-icons/lu';
|
|
2193
2213
|
import { motion } from 'motion/react';
|
|
2194
2214
|
|
|
2195
2215
|
interface DocsModalProps {
|
|
@@ -2197,10 +2217,6 @@ interface DocsModalProps {
|
|
|
2197
2217
|
onClose: () => void;
|
|
2198
2218
|
}
|
|
2199
2219
|
|
|
2200
|
-
const ARTICLES = [
|
|
2201
|
-
{ id: 'intro', title: '1. Welcome to Rakta.js', category: 'Getting Started', content: 'Rakta.js is a zero-dependency, ultra-fast structural core designed for creating high-performance, single-page web experiences.' }
|
|
2202
|
-
];
|
|
2203
|
-
|
|
2204
2220
|
export default function DocsModal({ isOpen, onClose }: DocsModalProps) {
|
|
2205
2221
|
if (!isOpen) return null;
|
|
2206
2222
|
return (
|
|
@@ -2211,7 +2227,7 @@ export default function DocsModal({ isOpen, onClose }: DocsModalProps) {
|
|
|
2211
2227
|
<Book className="w-5 h-5 text-rose-500" />
|
|
2212
2228
|
<h2 className="text-xl font-bold font-mono tracking-tight uppercase">Rakta.js <span className="text-rose-500">System Manual</span></h2>
|
|
2213
2229
|
</div>
|
|
2214
|
-
<button onClick={onClose} className="p-2 border border-white/30 hover:bg-rose-500 hover:text-white transition-colors cursor-pointer"><X className="w-5 h-5" /></button>
|
|
2230
|
+
<button type="button" onClick={onClose} className="p-2 border border-white/30 hover:bg-rose-500 hover:text-white transition-colors cursor-pointer"><X className="w-5 h-5" /></button>
|
|
2215
2231
|
</div>
|
|
2216
2232
|
<div className="p-10 text-white font-mono text-sm leading-relaxed max-w-3xl">
|
|
2217
2233
|
<h3 className="text-3xl font-extrabold text-rose-500 mb-6">Welcome to Rakta.js</h3>
|
|
@@ -2228,9 +2244,7 @@ export default function DocsModal({ isOpen, onClose }: DocsModalProps) {
|
|
|
2228
2244
|
);
|
|
2229
2245
|
}
|
|
2230
2246
|
`;
|
|
2231
|
-
var SHRIMP_CHARACTER_CODE = `
|
|
2232
|
-
|
|
2233
|
-
interface ShrimpCharacterProps {
|
|
2247
|
+
var SHRIMP_CHARACTER_CODE = `interface ShrimpCharacterProps {
|
|
2234
2248
|
status: 'IDLE' | 'SWIMMING' | 'JUMPING' | 'DEAD';
|
|
2235
2249
|
playerY: number;
|
|
2236
2250
|
rotation?: number;
|
|
@@ -2238,7 +2252,7 @@ interface ShrimpCharacterProps {
|
|
|
2238
2252
|
|
|
2239
2253
|
export default function ShrimpCharacter({ status, playerY, rotation }: ShrimpCharacterProps) {
|
|
2240
2254
|
let bodyClass = '';
|
|
2241
|
-
|
|
2255
|
+
const isDead = status === 'DEAD';
|
|
2242
2256
|
|
|
2243
2257
|
if (isDead) bodyClass = 'animate-bounce';
|
|
2244
2258
|
else if (status === 'SWIMMING') bodyClass = 'animate-pulse';
|
|
@@ -2250,9 +2264,9 @@ export default function ShrimpCharacter({ status, playerY, rotation }: ShrimpCha
|
|
|
2250
2264
|
return (
|
|
2251
2265
|
<div
|
|
2252
2266
|
className="relative w-16 h-16 flex items-center justify-center select-none pointer-events-none transition-transform duration-75"
|
|
2253
|
-
style={{ transform: \`rotate(\${finalRotation}deg)\` }}
|
|
2267
|
+
style={{ transform: \`translateY(\${-playerY}px) rotate(\${finalRotation}deg)\` }}
|
|
2254
2268
|
>
|
|
2255
|
-
<svg viewBox="0 0 100 100" className={\`w-full h-full drop-shadow-[0_4px_12px_rgba(244,63,94,0.3)] \${bodyClass}\`}>
|
|
2269
|
+
<svg aria-hidden="true" focusable="false" viewBox="0 0 100 100" className={\`w-full h-full drop-shadow-[0_4px_12px_rgba(244,63,94,0.3)] \${bodyClass}\`}>
|
|
2256
2270
|
<path d="M 30 46 C 25 32, 45 22, 58 28 C 65 31, 62 48, 55 54 C 44 58, 35 55, 30 46 Z" className={shrimpColor} />
|
|
2257
2271
|
<path d="M 55 30 C 65 24, 76 34, 74 46 C 72 54, 62 55, 55 48 Z" className={shrimpColor} />
|
|
2258
2272
|
<circle cx="66" cy="38" r="4.5" fill={isDead ? '#18181b' : '#000'} />
|
|
@@ -2268,7 +2282,11 @@ export default function ShrimpCharacter({ status, playerY, rotation }: ShrimpCha
|
|
|
2268
2282
|
}
|
|
2269
2283
|
`;
|
|
2270
2284
|
var WELCOME_PAGE_CODE = `import { useState } from "react";
|
|
2271
|
-
import {
|
|
2285
|
+
import { LuBook as Book, LuCloud as Cloud, LuCpu as Cpu } from "react-icons/lu";
|
|
2286
|
+
import ComponentsModal from "./components/ComponentsModal";
|
|
2287
|
+
import DeployModal from "./components/DeployModal";
|
|
2288
|
+
import DocsModal from "./components/DocsModal";
|
|
2289
|
+
import ShrimpCharacter from "./components/ShrimpCharacter";
|
|
2272
2290
|
|
|
2273
2291
|
export default function WelcomePage() {
|
|
2274
2292
|
const [modalOpen, setModalOpen] = useState<'components' | 'deploy' | 'docs' | null>(null);
|
|
@@ -2291,6 +2309,7 @@ export default function WelcomePage() {
|
|
|
2291
2309
|
|
|
2292
2310
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
2293
2311
|
<button
|
|
2312
|
+
type="button"
|
|
2294
2313
|
onClick={() => setModalOpen('components')}
|
|
2295
2314
|
className="flex flex-col items-center justify-center gap-3 p-6 border-2 border-zinc-800 bg-zinc-900/50 hover:border-rose-500 hover:bg-rose-500/10 transition-colors cursor-pointer group"
|
|
2296
2315
|
>
|
|
@@ -2299,6 +2318,7 @@ export default function WelcomePage() {
|
|
|
2299
2318
|
</button>
|
|
2300
2319
|
|
|
2301
2320
|
<button
|
|
2321
|
+
type="button"
|
|
2302
2322
|
onClick={() => setModalOpen('docs')}
|
|
2303
2323
|
className="flex flex-col items-center justify-center gap-3 p-6 border-2 border-zinc-800 bg-zinc-900/50 hover:border-blue-500 hover:bg-blue-500/10 transition-colors cursor-pointer group"
|
|
2304
2324
|
>
|
|
@@ -2307,6 +2327,7 @@ export default function WelcomePage() {
|
|
|
2307
2327
|
</button>
|
|
2308
2328
|
|
|
2309
2329
|
<button
|
|
2330
|
+
type="button"
|
|
2310
2331
|
onClick={() => setModalOpen('deploy')}
|
|
2311
2332
|
className="flex flex-col items-center justify-center gap-3 p-6 border-2 border-zinc-800 bg-zinc-900/50 hover:border-green-500 hover:bg-green-500/10 transition-colors cursor-pointer group"
|
|
2312
2333
|
>
|
|
@@ -2443,7 +2464,7 @@ function getFrontendOnlyFiles(projectConfig) {
|
|
|
2443
2464
|
typecheck: "tsc --noEmit"
|
|
2444
2465
|
},
|
|
2445
2466
|
dependencies: {
|
|
2446
|
-
raktajs: "^0.1.
|
|
2467
|
+
raktajs: "^0.1.7",
|
|
2447
2468
|
react: "^19.2.7",
|
|
2448
2469
|
"react-dom": "^19.2.7",
|
|
2449
2470
|
"react-icons": "^5.2.1",
|
|
@@ -2573,7 +2594,7 @@ function getFullstackFrontendFiles(projectConfig) {
|
|
|
2573
2594
|
typecheck: "tsc --noEmit"
|
|
2574
2595
|
},
|
|
2575
2596
|
dependencies: {
|
|
2576
|
-
raktajs: "^0.1.
|
|
2597
|
+
raktajs: "^0.1.7",
|
|
2577
2598
|
react: "^19.2.7",
|
|
2578
2599
|
"react-dom": "^19.2.7",
|
|
2579
2600
|
"react-icons": "^5.2.1",
|
|
@@ -4410,21 +4431,21 @@ function getProjectNameFromArgs(cliArgs) {
|
|
|
4410
4431
|
}
|
|
4411
4432
|
function formatFullstackCommands() {
|
|
4412
4433
|
return [
|
|
4413
|
-
|
|
4414
|
-
"cd frontend",
|
|
4415
|
-
"bun install",
|
|
4416
|
-
"bun run dev",
|
|
4434
|
+
import_picocolors.default.dim("# Terminal 1"),
|
|
4435
|
+
import_picocolors.default.cyan("cd frontend"),
|
|
4436
|
+
import_picocolors.default.cyan("bun install"),
|
|
4437
|
+
import_picocolors.default.cyan("bun run dev"),
|
|
4417
4438
|
"",
|
|
4418
|
-
|
|
4419
|
-
"cd backend",
|
|
4420
|
-
"bun install",
|
|
4421
|
-
"bun run dev"
|
|
4422
|
-
].join(`
|
|
4423
|
-
|
|
4439
|
+
import_picocolors.default.dim("# Terminal 2"),
|
|
4440
|
+
import_picocolors.default.cyan("cd backend"),
|
|
4441
|
+
import_picocolors.default.cyan("bun install"),
|
|
4442
|
+
import_picocolors.default.cyan("bun run dev")
|
|
4443
|
+
].map((line) => line.length === 0 ? "" : ` ${line}`).join(`
|
|
4444
|
+
`);
|
|
4424
4445
|
}
|
|
4425
4446
|
function formatFrontendOnlyCommands(projectName) {
|
|
4426
|
-
return [`cd ${projectName}`, "bun install", "bun run dev"].join(`
|
|
4427
|
-
|
|
4447
|
+
return [`cd ${projectName}`, "bun install", "bun run dev"].map((command) => ` ${import_picocolors.default.cyan(command)}`).join(`
|
|
4448
|
+
`);
|
|
4428
4449
|
}
|
|
4429
4450
|
function printSuccessMessage(projectConfig) {
|
|
4430
4451
|
const modeLabel = PROJECT_MODE_DISPLAY[projectConfig.projectMode];
|
|
@@ -4445,7 +4466,7 @@ function printSuccessMessage(projectConfig) {
|
|
|
4445
4466
|
|
|
4446
4467
|
${import_picocolors.default.bold("Next steps:")}
|
|
4447
4468
|
|
|
4448
|
-
|
|
4469
|
+
${nextSteps}
|
|
4449
4470
|
|
|
4450
4471
|
${import_picocolors.default.bold("Frontend:")} ${import_picocolors.default.cyan("http://localhost:3000")}
|
|
4451
4472
|
${isFullstack ? `${import_picocolors.default.bold("Backend:")} ${import_picocolors.default.cyan("http://localhost:4000")}` : ""}
|
|
@@ -4485,4 +4506,4 @@ Error: ${errorMessage}
|
|
|
4485
4506
|
process.exit(1);
|
|
4486
4507
|
});
|
|
4487
4508
|
|
|
4488
|
-
//# debugId=
|
|
4509
|
+
//# debugId=2E17890E5DBF1B0764756E2164756E21
|