flashts 1.0.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.
@@ -0,0 +1,171 @@
1
+ import { X, Zap, Coffee, ExternalLink } from "lucide-react";
2
+ import { createPortal } from "react-dom";
3
+ import clsx from "clsx";
4
+
5
+ interface WelcomeScreenProps {
6
+ isOpen: boolean;
7
+ onClose: () => void;
8
+ showOnStartup: boolean;
9
+ onToggleStartup: (value: boolean) => void;
10
+ }
11
+
12
+ export function WelcomeScreen({ isOpen, onClose, showOnStartup, onToggleStartup }: WelcomeScreenProps) {
13
+ if (!isOpen) return null;
14
+
15
+ return createPortal(
16
+ <div className="fixed inset-0 z-[20000] flex items-center justify-center p-4 md:p-6 overflow-y-auto">
17
+ {/* Background Backdrop */}
18
+ <div
19
+ className="fixed inset-0 bg-black/80 backdrop-blur-md transition-opacity"
20
+ onClick={onClose}
21
+ />
22
+
23
+ {/* Modal Content */}
24
+ <div className={clsx(
25
+ "relative w-full max-w-2xl bg-[#09090b] border border-border-color rounded-2xl shadow-2xl overflow-hidden",
26
+ "animate-modal my-auto flex flex-col max-h-[90vh] md:max-h-none"
27
+ )}>
28
+ {/* Header Decor */}
29
+ <div className="absolute top-0 inset-x-0 h-1 bg-gradient-to-r from-transparent via-accent-primary to-transparent opacity-50" />
30
+
31
+ <div className="p-5 md:p-8 flex flex-col h-full overflow-y-auto no-scrollbar">
32
+ {/* Header */}
33
+ <div className="flex justify-between items-start mb-6 md:mb-8">
34
+ <div className="flex items-center gap-3 md:gap-4">
35
+ <div className="h-10 w-10 md:h-14 md:w-14 rounded-xl md:rounded-2xl bg-accent-primary/10 flex-center text-accent-primary shrink-0 transition-transform hover:scale-110">
36
+ <Zap size={24} className="md:w-8 md:h-8" />
37
+ </div>
38
+ <div>
39
+ <h2 className="text-xl md:text-3xl font-black tracking-tight text-white leading-tight">
40
+ Welcome to <span className="text-accent-primary">FlashTS</span>
41
+ </h2>
42
+ <p className="text-text-secondary text-xs md:text-sm">Ultra-fast JavaScript/TypeScript Playground</p>
43
+ </div>
44
+ </div>
45
+ <button
46
+ onClick={onClose}
47
+ className="p-2 hover:bg-white/5 rounded-full text-text-secondary hover:text-white transition-colors shrink-0"
48
+ >
49
+ <X size={20} className="md:w-6 md:h-6" />
50
+ </button>
51
+ </div>
52
+
53
+ {/* Features Grid */}
54
+ <div className="grid grid-cols-1 sm:grid-cols-2 gap-3 md:gap-6 mb-6 md:mb-8">
55
+ <FeatureCard
56
+ icon={<Zap size={18} />}
57
+ title="Bun Powered"
58
+ desc="Instant execution with Bun's runtime."
59
+ color="blue"
60
+ />
61
+ <FeatureCard
62
+ icon={<Coffee size={18} />}
63
+ title="Multi-File"
64
+ desc="Full project with tabbed imports."
65
+ color="orange"
66
+ />
67
+ <FeatureCard
68
+ icon={<Check size={18} />}
69
+ title="IntelliSense"
70
+ desc="Pro autocomplete for NPM packages."
71
+ color="green"
72
+ />
73
+ <FeatureCard
74
+ icon={<ExternalLink size={18} />}
75
+ title="Zero Config"
76
+ desc="Auto-setup for maximum speed."
77
+ color="purple"
78
+ />
79
+ </div>
80
+
81
+ {/* Shortcuts Section - Hidden on very small screens to save space */}
82
+ <div className="bg-bg-secondary/50 rounded-xl p-4 border border-border-color mb-6 md:mb-8 hidden xs:block">
83
+ <h4 className="text-[10px] md:text-xs font-bold text-text-secondary uppercase tracking-widest mb-3">Key Shortcuts</h4>
84
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-2">
85
+ <Shortcut label="Run Project" keys="Ctrl + Shift + F" />
86
+ <Shortcut label="NPM Manager" keys="Ctrl + Shift + L" />
87
+ </div>
88
+ </div>
89
+
90
+ {/* Footer */}
91
+ <div className="flex flex-col sm:flex-row items-center justify-between gap-4 mt-auto pt-4 border-t border-white/5">
92
+ <div className="flex items-center gap-3 w-full sm:w-auto">
93
+ <label className="flex items-center gap-3 cursor-pointer group">
94
+ <div
95
+ onClick={() => onToggleStartup(!showOnStartup)}
96
+ className={clsx(
97
+ "w-10 h-5 md:w-12 md:h-6 rounded-full transition-all relative",
98
+ showOnStartup ? 'bg-accent-primary' : 'bg-bg-tertiary'
99
+ )}
100
+ >
101
+ <div className={clsx(
102
+ "absolute top-1 left-1 w-3 h-3 md:w-4 md:h-4 rounded-full bg-white shadow-sm transition-transform",
103
+ showOnStartup ? 'translate-x-5 md:translate-x-6' : 'translate-x-0'
104
+ )} />
105
+ </div>
106
+ <span className="text-xs text-text-secondary group-hover:text-text-primary transition-colors font-medium select-none">Show on startup</span>
107
+ </label>
108
+ </div>
109
+
110
+ <button
111
+ onClick={onClose}
112
+ className="w-full sm:w-32 py-2.5 md:py-3 btn-primary text-sm font-bold shadow-lg shadow-accent-primary/10"
113
+ >
114
+ Get Started
115
+ </button>
116
+ </div>
117
+ </div>
118
+ </div>
119
+ </div>,
120
+ document.body
121
+ );
122
+ }
123
+
124
+ function FeatureCard({ icon, title, desc, color }: { icon: React.ReactNode, title: string, desc: string, color: string }) {
125
+ const colors: Record<string, string> = {
126
+ blue: "bg-blue-500/10 text-blue-400",
127
+ orange: "bg-orange-500/10 text-orange-400",
128
+ green: "bg-green-500/10 text-green-400",
129
+ purple: "bg-purple-500/10 text-purple-400"
130
+ };
131
+ return (
132
+ <div className="p-3 md:p-4 rounded-xl bg-white/5 border border-white/5 flex items-start gap-3 hover:bg-white/[0.08] transition-colors group">
133
+ <div className={clsx("p-2 rounded-lg shrink-0 group-hover:scale-110 transition-transform", colors[color])}>
134
+ {icon}
135
+ </div>
136
+ <div>
137
+ <h4 className="font-bold text-white text-sm md:text-base mb-0.5">{title}</h4>
138
+ <p className="text-[10px] md:text-xs text-text-secondary leading-relaxed">{desc}</p>
139
+ </div>
140
+ </div>
141
+ );
142
+ }
143
+
144
+ function Shortcut({ label, keys }: { label: string, keys: string }) {
145
+ return (
146
+ <div className="flex justify-between items-center px-3 py-2 bg-black/20 rounded-lg hover:bg-black/30 transition-colors">
147
+ <span className="text-[10px] md:text-xs text-text-primary font-medium">{label}</span>
148
+ <kbd className="text-[9px] md:text-[10px] bg-bg-tertiary px-1.5 py-0.5 rounded border border-white/10 font-mono text-text-secondary shadow-sm lowercase">
149
+ {keys}
150
+ </kbd>
151
+ </div>
152
+ );
153
+ }
154
+
155
+ function Check({ size, className }: { size: number, className?: string }) {
156
+ return (
157
+ <svg
158
+ width={size}
159
+ height={size}
160
+ viewBox="0 0 24 24"
161
+ fill="none"
162
+ stroke="currentColor"
163
+ strokeWidth="3"
164
+ strokeLinecap="round"
165
+ strokeLinejoin="round"
166
+ className={className}
167
+ >
168
+ <polyline points="20 6 9 17 4 12" />
169
+ </svg>
170
+ );
171
+ }
@@ -0,0 +1,142 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ :root {
6
+ --bg-primary: #09090b;
7
+ --bg-secondary: #18181b;
8
+ --bg-tertiary: #27272a;
9
+ --accent-primary: #f59e0b; /* Amber 500 */
10
+ --accent-glow: rgba(245, 158, 11, 0.5);
11
+ --text-primary: #f4f4f5;
12
+ --text-secondary: #a1a1aa;
13
+ --border-color: #27272a;
14
+ --font-mono:
15
+ "JetBrains Mono", "Fira Code", source-code-pro, Menlo, Monaco, Consolas,
16
+ "Courier New", monospace;
17
+ --font-sans:
18
+ "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
19
+ Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
20
+ }
21
+
22
+ * {
23
+ box-sizing: border-box;
24
+ margin: 0;
25
+ padding: 0;
26
+ }
27
+
28
+ body {
29
+ background-color: var(--bg-primary);
30
+ color: var(--text-primary);
31
+ font-family: var(--font-sans);
32
+ overflow: hidden; /* App like feel */
33
+ -webkit-font-smoothing: antialiased;
34
+ -moz-osx-font-smoothing: grayscale;
35
+ }
36
+
37
+ /* Scrollbar */
38
+ ::-webkit-scrollbar {
39
+ width: 8px;
40
+ height: 8px;
41
+ }
42
+ ::-webkit-scrollbar-track {
43
+ background: var(--bg-primary);
44
+ }
45
+ ::-webkit-scrollbar-thumb {
46
+ background: var(--bg-tertiary);
47
+ border-radius: 4px;
48
+ }
49
+ ::-webkit-scrollbar-thumb:hover {
50
+ background: #3f3f46;
51
+ }
52
+
53
+ /* Utility Classes */
54
+ .glass {
55
+ background: rgba(24, 24, 27, 0.6);
56
+ backdrop-filter: blur(12px);
57
+ border: 1px solid rgba(255, 255, 255, 0.05);
58
+ }
59
+
60
+ .flex-center {
61
+ display: flex;
62
+ align-items: center;
63
+ justify-content: center;
64
+ }
65
+
66
+ .no-scrollbar::-webkit-scrollbar {
67
+ display: none;
68
+ }
69
+ .no-scrollbar {
70
+ -ms-overflow-style: none;
71
+ scrollbar-width: none;
72
+ }
73
+
74
+ /* Animations */
75
+ @keyframes glow {
76
+ 0% {
77
+ box-shadow: 0 0 5px var(--accent-glow);
78
+ }
79
+ 50% {
80
+ box-shadow: 0 0 20px var(--accent-glow);
81
+ }
82
+ 100% {
83
+ box-shadow: 0 0 5px var(--accent-glow);
84
+ }
85
+ }
86
+
87
+ @keyframes modal-entrance {
88
+ 0% {
89
+ opacity: 0;
90
+ transform: scale(0.9) translateY(20px);
91
+ filter: blur(10px);
92
+ }
93
+ 60% {
94
+ transform: scale(1.02) translateY(-5px);
95
+ filter: blur(0);
96
+ }
97
+ 100% {
98
+ opacity: 1;
99
+ transform: scale(1) translateY(0);
100
+ }
101
+ }
102
+
103
+ .animate-modal {
104
+ animation: modal-entrance 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
105
+ }
106
+
107
+ .btn-primary {
108
+ background: linear-gradient(135deg, #f59e0b, #ea580c);
109
+ color: white;
110
+ border: none;
111
+ padding: 0.5rem 1.5rem;
112
+ border-radius: 8px;
113
+ font-weight: 600;
114
+ cursor: pointer;
115
+ transition: all 0.2s ease;
116
+ display: flex;
117
+ align-items: center;
118
+ gap: 0.5rem;
119
+ }
120
+
121
+ .btn-primary:hover {
122
+ transform: translateY(-1px);
123
+ box-shadow: 0 4px 12px var(--accent-glow);
124
+ }
125
+
126
+ .btn-primary:active {
127
+ transform: translateY(0);
128
+ }
129
+
130
+ .panel-header {
131
+ height: 48px;
132
+ padding: 0 1rem;
133
+ display: flex;
134
+ align-items: center;
135
+ justify-content: space-between;
136
+ border-bottom: 1px solid var(--border-color);
137
+ background: var(--bg-secondary);
138
+ font-size: 0.875rem;
139
+ font-weight: 500;
140
+ color: var(--text-secondary);
141
+ user-select: none;
142
+ }
@@ -0,0 +1,10 @@
1
+ import { StrictMode } from 'react'
2
+ import { createRoot } from 'react-dom/client'
3
+ import './index.css'
4
+ import App from './App.tsx'
5
+
6
+ createRoot(document.getElementById('root')!).render(
7
+ <StrictMode>
8
+ <App />
9
+ </StrictMode>,
10
+ )
@@ -0,0 +1,32 @@
1
+ /** @type {import('tailwindcss').Config} */
2
+ export default {
3
+ content: [
4
+ "./index.html",
5
+ "./src/**/*.{js,ts,jsx,tsx}",
6
+ ],
7
+ theme: {
8
+ extend: {
9
+ colors: {
10
+ bg: {
11
+ primary: "var(--bg-primary)",
12
+ secondary: "var(--bg-secondary)",
13
+ tertiary: "var(--bg-tertiary)",
14
+ },
15
+ accent: {
16
+ primary: "var(--accent-primary)",
17
+ glow: "var(--accent-glow)",
18
+ },
19
+ text: {
20
+ primary: "var(--text-primary)",
21
+ secondary: "var(--text-secondary)",
22
+ },
23
+ "border-color": "var(--border-color)",
24
+ },
25
+ fontFamily: {
26
+ mono: "var(--font-mono)",
27
+ sans: "var(--font-sans)",
28
+ },
29
+ },
30
+ },
31
+ plugins: [],
32
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "compilerOptions": {
3
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
4
+ "target": "ES2022",
5
+ "useDefineForClassFields": true,
6
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
7
+ "module": "ESNext",
8
+ "types": ["vite/client"],
9
+ "skipLibCheck": true,
10
+
11
+ /* Bundler mode */
12
+ "moduleResolution": "bundler",
13
+ "allowImportingTsExtensions": true,
14
+ "verbatimModuleSyntax": true,
15
+ "moduleDetection": "force",
16
+ "noEmit": true,
17
+ "jsx": "react-jsx",
18
+
19
+ /* Linting */
20
+ "strict": true,
21
+ "noUnusedLocals": true,
22
+ "noUnusedParameters": true,
23
+ "erasableSyntaxOnly": true,
24
+ "noFallthroughCasesInSwitch": true,
25
+ "noUncheckedSideEffectImports": true
26
+ },
27
+ "include": ["src"]
28
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "files": [],
3
+ "references": [
4
+ { "path": "./tsconfig.app.json" },
5
+ { "path": "./tsconfig.node.json" }
6
+ ]
7
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "compilerOptions": {
3
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
4
+ "target": "ES2023",
5
+ "lib": ["ES2023"],
6
+ "module": "ESNext",
7
+ "types": ["node"],
8
+ "skipLibCheck": true,
9
+
10
+ /* Bundler mode */
11
+ "moduleResolution": "bundler",
12
+ "allowImportingTsExtensions": true,
13
+ "verbatimModuleSyntax": true,
14
+ "moduleDetection": "force",
15
+ "noEmit": true,
16
+
17
+ /* Linting */
18
+ "strict": true,
19
+ "noUnusedLocals": true,
20
+ "noUnusedParameters": true,
21
+ "erasableSyntaxOnly": true,
22
+ "noFallthroughCasesInSwitch": true,
23
+ "noUncheckedSideEffectImports": true
24
+ },
25
+ "include": ["vite.config.ts"]
26
+ }
@@ -0,0 +1,7 @@
1
+ import { defineConfig } from 'vite'
2
+ import react from '@vitejs/plugin-react'
3
+
4
+ // https://vite.dev/config/
5
+ export default defineConfig({
6
+ plugins: [react()],
7
+ })
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "flashts",
3
+ "version": "1.0.0",
4
+ "description": "High-performance TypeScript/JavaScript Playground powered by Bun",
5
+ "main": "server/index.ts",
6
+ "bin": {
7
+ "flashts": "./bin/cli.ts"
8
+ },
9
+ "type": "module",
10
+ "scripts": {
11
+ "dev:client": "cd client && vite",
12
+ "dev:server": "cd server && bun index.ts",
13
+ "build": "cd client && bun run build",
14
+ "start": "bun bin/cli.ts"
15
+ },
16
+ "dependencies": {
17
+ "@hono/node-server": "^1.13.8",
18
+ "@monaco-editor/react": "^4.7.0",
19
+ "clsx": "^2.1.1",
20
+ "commander": "^13.1.0",
21
+ "framer-motion": "^12.29.0",
22
+ "hono": "^4.11.5",
23
+ "localtunnel": "^2.0.2",
24
+ "lucide-react": "^0.562.0",
25
+ "monaco-editor": "^0.55.1",
26
+ "open": "^10.1.0",
27
+ "picocolors": "^1.1.1",
28
+ "react": "^19.2.3",
29
+ "react-dom": "^19.2.0",
30
+ "react-resizable-panels": "^4.4.1",
31
+ "tailwind-merge": "^3.4.0"
32
+ },
33
+ "devDependencies": {
34
+ "@eslint/js": "^9.39.1",
35
+ "@types/bun": "latest",
36
+ "@types/localtunnel": "^2.0.4",
37
+ "@types/node": "^24.10.1",
38
+ "@types/react": "^19.2.9",
39
+ "@types/react-dom": "^19.2.3",
40
+ "@vitejs/plugin-react": "^5.1.1",
41
+ "autoprefixer": "^10.4.23",
42
+ "eslint": "^9.39.1",
43
+ "eslint-plugin-react-hooks": "^7.0.1",
44
+ "eslint-plugin-react-refresh": "^0.4.24",
45
+ "globals": "^16.5.0",
46
+ "postcss": "^8.5.6",
47
+ "tailwindcss": "3.4.17",
48
+ "typescript": "~5.9.3",
49
+ "typescript-eslint": "^8.46.4",
50
+ "vite": "npm:rolldown-vite@7.2.5"
51
+ },
52
+ "overrides": {
53
+ "vite": "npm:rolldown-vite@7.2.5"
54
+ },
55
+ "keywords": [
56
+ "typescript",
57
+ "playground",
58
+ "bun",
59
+ "hono",
60
+ "react",
61
+ "ide",
62
+ "cli"
63
+ ],
64
+ "author": "FlashTS Team",
65
+ "license": "MIT"
66
+ }
@@ -0,0 +1,15 @@
1
+ # server
2
+
3
+ To install dependencies:
4
+
5
+ ```bash
6
+ bun install
7
+ ```
8
+
9
+ To run:
10
+
11
+ ```bash
12
+ bun run index.ts
13
+ ```
14
+
15
+ This project was created using `bun init` in bun v1.3.6. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.
@@ -0,0 +1,42 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "configVersion": 1,
4
+ "workspaces": {
5
+ "": {
6
+ "name": "server",
7
+ "dependencies": {
8
+ "@pulse-js/core": "^0.2.2",
9
+ "@types/react": "^19.2.9",
10
+ "hono": "^4.11.5",
11
+ "react": "^19.2.3",
12
+ },
13
+ "devDependencies": {
14
+ "@types/bun": "latest",
15
+ },
16
+ "peerDependencies": {
17
+ "typescript": "^5",
18
+ },
19
+ },
20
+ },
21
+ "packages": {
22
+ "@pulse-js/core": ["@pulse-js/core@0.2.2", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-iUbPPsp6UU+erfmKe7Y1wsMHmJsQImlata2HA2benjWpdHp7sC3YSBRjAyRVty5gVDx5ZewSDuA77epCIHfR8Q=="],
23
+
24
+ "@types/bun": ["@types/bun@1.3.6", "", { "dependencies": { "bun-types": "1.3.6" } }, "sha512-uWCv6FO/8LcpREhenN1d1b6fcspAB+cefwD7uti8C8VffIv0Um08TKMn98FynpTiU38+y2dUO55T11NgDt8VAA=="],
25
+
26
+ "@types/node": ["@types/node@25.0.10", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg=="],
27
+
28
+ "@types/react": ["@types/react@19.2.9", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-Lpo8kgb/igvMIPeNV2rsYKTgaORYdO1XGVZ4Qz3akwOj0ySGYMPlQWa8BaLn0G63D1aSaAQ5ldR06wCpChQCjA=="],
29
+
30
+ "bun-types": ["bun-types@1.3.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ=="],
31
+
32
+ "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
33
+
34
+ "hono": ["hono@4.11.5", "", {}, "sha512-WemPi9/WfyMwZs+ZUXdiwcCh9Y+m7L+8vki9MzDw3jJ+W9Lc+12HGsd368Qc1vZi1xwW8BWMMsnK5efYKPdt4g=="],
35
+
36
+ "react": ["react@19.2.3", "", {}, "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA=="],
37
+
38
+ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
39
+
40
+ "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
41
+ }
42
+ }