create-fluxstack 1.10.1 → 1.12.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.
- package/.dockerignore +1 -2
- package/Dockerfile +8 -8
- package/LLMD/INDEX.md +64 -0
- package/LLMD/MAINTENANCE.md +197 -0
- package/LLMD/MIGRATION.md +156 -0
- package/LLMD/config/.gitkeep +1 -0
- package/LLMD/config/declarative-system.md +268 -0
- package/LLMD/config/environment-vars.md +327 -0
- package/LLMD/config/runtime-reload.md +401 -0
- package/LLMD/core/.gitkeep +1 -0
- package/LLMD/core/build-system.md +599 -0
- package/LLMD/core/framework-lifecycle.md +229 -0
- package/LLMD/core/plugin-system.md +451 -0
- package/LLMD/patterns/.gitkeep +1 -0
- package/LLMD/patterns/anti-patterns.md +297 -0
- package/LLMD/patterns/project-structure.md +264 -0
- package/LLMD/patterns/type-safety.md +440 -0
- package/LLMD/reference/.gitkeep +1 -0
- package/LLMD/reference/cli-commands.md +250 -0
- package/LLMD/reference/plugin-hooks.md +357 -0
- package/LLMD/reference/routing.md +39 -0
- package/LLMD/reference/troubleshooting.md +364 -0
- package/LLMD/resources/.gitkeep +1 -0
- package/LLMD/resources/controllers.md +465 -0
- package/LLMD/resources/live-components.md +703 -0
- package/LLMD/resources/live-rooms.md +482 -0
- package/LLMD/resources/live-upload.md +130 -0
- package/LLMD/resources/plugins-external.md +617 -0
- package/LLMD/resources/routes-eden.md +254 -0
- package/README.md +37 -17
- package/app/client/index.html +0 -1
- package/app/client/src/App.tsx +107 -150
- package/app/client/src/components/AppLayout.tsx +68 -0
- package/app/client/src/components/BackButton.tsx +13 -0
- package/app/client/src/components/DemoPage.tsx +20 -0
- package/app/client/src/components/LiveUploadWidget.tsx +204 -0
- package/app/client/src/lib/eden-api.ts +85 -60
- package/app/client/src/live/ChatDemo.tsx +107 -0
- package/app/client/src/live/CounterDemo.tsx +206 -0
- package/app/client/src/live/FormDemo.tsx +119 -0
- package/app/client/src/live/RoomChatDemo.tsx +242 -0
- package/app/client/src/live/UploadDemo.tsx +21 -0
- package/app/client/src/main.tsx +4 -1
- package/app/client/src/pages/ApiTestPage.tsx +108 -0
- package/app/client/src/pages/HomePage.tsx +76 -0
- package/app/server/app.ts +1 -4
- package/app/server/controllers/users.controller.ts +36 -44
- package/app/server/index.ts +25 -35
- package/app/server/live/LiveChat.ts +77 -0
- package/app/server/live/LiveCounter.ts +67 -0
- package/app/server/live/LiveForm.ts +63 -0
- package/app/server/live/LiveLocalCounter.ts +32 -0
- package/app/server/live/LiveRoomChat.ts +285 -0
- package/app/server/live/LiveUpload.ts +81 -0
- package/app/server/routes/index.ts +3 -1
- package/app/server/routes/room.routes.ts +117 -0
- package/app/server/routes/users.routes.ts +35 -27
- package/app/shared/types/index.ts +14 -2
- package/config/app.config.ts +2 -62
- package/config/client.config.ts +2 -95
- package/config/database.config.ts +2 -99
- package/config/fluxstack.config.ts +25 -45
- package/config/index.ts +57 -38
- package/config/monitoring.config.ts +2 -114
- package/config/plugins.config.ts +2 -80
- package/config/server.config.ts +2 -68
- package/config/services.config.ts +2 -130
- package/config/system/app.config.ts +29 -0
- package/config/system/build.config.ts +49 -0
- package/config/system/client.config.ts +68 -0
- package/config/system/database.config.ts +17 -0
- package/config/system/fluxstack.config.ts +114 -0
- package/config/{logger.config.ts → system/logger.config.ts} +3 -1
- package/config/system/monitoring.config.ts +114 -0
- package/config/system/plugins.config.ts +84 -0
- package/config/{runtime.config.ts → system/runtime.config.ts} +1 -1
- package/config/system/server.config.ts +68 -0
- package/config/system/services.config.ts +46 -0
- package/config/{system.config.ts → system/system.config.ts} +1 -1
- package/core/build/flux-plugins-generator.ts +325 -325
- package/core/build/index.ts +39 -27
- package/core/build/live-components-generator.ts +3 -3
- package/core/build/optimizer.ts +235 -235
- package/core/cli/command-registry.ts +6 -4
- package/core/cli/commands/build.ts +79 -0
- package/core/cli/commands/create.ts +54 -0
- package/core/cli/commands/dev.ts +101 -0
- package/core/cli/commands/help.ts +34 -0
- package/core/cli/commands/index.ts +34 -0
- package/core/cli/commands/make-plugin.ts +90 -0
- package/core/cli/commands/plugin-add.ts +197 -0
- package/core/cli/commands/plugin-deps.ts +2 -2
- package/core/cli/commands/plugin-list.ts +208 -0
- package/core/cli/commands/plugin-remove.ts +170 -0
- package/core/cli/generators/component.ts +769 -769
- package/core/cli/generators/controller.ts +1 -1
- package/core/cli/generators/index.ts +146 -146
- package/core/cli/generators/interactive.ts +227 -227
- package/core/cli/generators/plugin.ts +2 -2
- package/core/cli/generators/prompts.ts +82 -82
- package/core/cli/generators/route.ts +6 -6
- package/core/cli/generators/service.ts +2 -2
- package/core/cli/generators/template-engine.ts +4 -3
- package/core/cli/generators/types.ts +2 -2
- package/core/cli/generators/utils.ts +191 -191
- package/core/cli/index.ts +115 -686
- package/core/cli/plugin-discovery.ts +2 -2
- package/core/client/LiveComponentsProvider.tsx +60 -8
- package/core/client/api/eden.ts +183 -0
- package/core/client/api/index.ts +11 -0
- package/core/client/components/Live.tsx +104 -0
- package/core/client/fluxstack.ts +1 -9
- package/core/client/hooks/AdaptiveChunkSizer.ts +215 -215
- package/core/client/hooks/state-validator.ts +1 -1
- package/core/client/hooks/useAuth.ts +48 -48
- package/core/client/hooks/useChunkedUpload.ts +85 -35
- package/core/client/hooks/useLiveChunkedUpload.ts +87 -0
- package/core/client/hooks/useLiveComponent.ts +800 -0
- package/core/client/hooks/useLiveUpload.ts +71 -0
- package/core/client/hooks/useRoom.ts +409 -0
- package/core/client/hooks/useRoomProxy.ts +382 -0
- package/core/client/index.ts +17 -68
- package/core/client/standalone-entry.ts +8 -0
- package/core/client/standalone.ts +74 -53
- package/core/client/state/createStore.ts +192 -192
- package/core/client/state/index.ts +14 -14
- package/core/config/index.ts +70 -291
- package/core/config/schema.ts +42 -723
- package/core/framework/client.ts +131 -131
- package/core/framework/index.ts +7 -7
- package/core/framework/server.ts +47 -40
- package/core/framework/types.ts +2 -2
- package/core/index.ts +23 -4
- package/core/live/ComponentRegistry.ts +3 -3
- package/core/live/types.ts +77 -0
- package/core/plugins/built-in/index.ts +134 -134
- package/core/plugins/built-in/live-components/commands/create-live-component.ts +242 -1066
- package/core/plugins/built-in/live-components/index.ts +1 -1
- package/core/plugins/built-in/monitoring/index.ts +111 -47
- package/core/plugins/built-in/static/index.ts +1 -1
- package/core/plugins/built-in/swagger/index.ts +68 -265
- package/core/plugins/built-in/vite/index.ts +85 -185
- package/core/plugins/built-in/vite/vite-dev.ts +10 -16
- package/core/plugins/config.ts +9 -7
- package/core/plugins/dependency-manager.ts +31 -1
- package/core/plugins/discovery.ts +19 -7
- package/core/plugins/executor.ts +2 -2
- package/core/plugins/index.ts +203 -203
- package/core/plugins/manager.ts +27 -39
- package/core/plugins/module-resolver.ts +19 -8
- package/core/plugins/registry.ts +255 -19
- package/core/plugins/types.ts +20 -53
- package/core/server/framework.ts +66 -43
- package/core/server/index.ts +15 -15
- package/core/server/live/ComponentRegistry.ts +78 -71
- package/core/server/live/FileUploadManager.ts +23 -10
- package/core/server/live/LiveComponentPerformanceMonitor.ts +1 -1
- package/core/server/live/LiveRoomManager.ts +261 -0
- package/core/server/live/RoomEventBus.ts +234 -0
- package/core/server/live/RoomStateManager.ts +172 -0
- package/core/server/live/StateSignature.ts +643 -643
- package/core/server/live/WebSocketConnectionManager.ts +30 -19
- package/core/server/live/auto-generated-components.ts +21 -9
- package/core/server/live/index.ts +14 -0
- package/core/server/live/websocket-plugin.ts +214 -67
- package/core/server/middleware/elysia-helpers.ts +7 -2
- package/core/server/middleware/errorHandling.ts +1 -1
- package/core/server/middleware/index.ts +31 -31
- package/core/server/plugins/database.ts +180 -180
- package/core/server/plugins/static-files-plugin.ts +69 -69
- package/core/server/plugins/swagger.ts +1 -1
- package/core/server/rooms/RoomBroadcaster.ts +357 -0
- package/core/server/rooms/RoomSystem.ts +463 -0
- package/core/server/rooms/index.ts +13 -0
- package/core/server/services/BaseService.ts +1 -1
- package/core/server/services/ServiceContainer.ts +1 -1
- package/core/server/services/index.ts +8 -8
- package/core/templates/create-project.ts +12 -12
- package/core/testing/index.ts +9 -9
- package/core/testing/setup.ts +73 -73
- package/core/types/api.ts +168 -168
- package/core/types/build.ts +219 -219
- package/core/types/config.ts +56 -26
- package/core/types/index.ts +4 -4
- package/core/types/plugin.ts +107 -107
- package/core/types/types.ts +353 -14
- package/core/utils/build-logger.ts +324 -324
- package/core/utils/config-schema.ts +480 -480
- package/core/utils/env.ts +2 -8
- package/core/utils/errors/codes.ts +114 -114
- package/core/utils/errors/handlers.ts +36 -1
- package/core/utils/errors/index.ts +49 -5
- package/core/utils/errors/middleware.ts +113 -113
- package/core/utils/helpers.ts +6 -16
- package/core/utils/index.ts +17 -17
- package/core/utils/logger/colors.ts +114 -114
- package/core/utils/logger/config.ts +13 -9
- package/core/utils/logger/formatter.ts +82 -82
- package/core/utils/logger/group-logger.ts +101 -101
- package/core/utils/logger/index.ts +6 -1
- package/core/utils/logger/stack-trace.ts +3 -1
- package/core/utils/logger/startup-banner.ts +82 -82
- package/core/utils/logger/winston-logger.ts +152 -152
- package/core/utils/monitoring/index.ts +211 -211
- package/core/utils/sync-version.ts +66 -66
- package/core/utils/version.ts +1 -1
- package/create-fluxstack.ts +8 -7
- package/package.json +12 -13
- package/plugins/crypto-auth/cli/make-protected-route.command.ts +1 -1
- package/plugins/crypto-auth/client/CryptoAuthClient.ts +302 -302
- package/plugins/crypto-auth/client/components/index.ts +11 -11
- package/plugins/crypto-auth/client/index.ts +11 -11
- package/plugins/crypto-auth/config/index.ts +1 -1
- package/plugins/crypto-auth/index.ts +4 -4
- package/plugins/crypto-auth/package.json +65 -65
- package/plugins/crypto-auth/server/AuthMiddleware.ts +1 -1
- package/plugins/crypto-auth/server/CryptoAuthService.ts +185 -185
- package/plugins/crypto-auth/server/index.ts +21 -21
- package/plugins/crypto-auth/server/middlewares/cryptoAuthAdmin.ts +3 -3
- package/plugins/crypto-auth/server/middlewares/cryptoAuthOptional.ts +1 -1
- package/plugins/crypto-auth/server/middlewares/cryptoAuthPermissions.ts +2 -2
- package/plugins/crypto-auth/server/middlewares/cryptoAuthRequired.ts +2 -2
- package/plugins/crypto-auth/server/middlewares/helpers.ts +1 -1
- package/plugins/crypto-auth/server/middlewares/index.ts +22 -22
- package/tsconfig.api-strict.json +16 -0
- package/tsconfig.json +48 -52
- package/{app/client/tsconfig.node.json → tsconfig.node.json} +25 -25
- package/types/global.d.ts +29 -29
- package/types/vitest.d.ts +8 -8
- package/vite.config.ts +38 -62
- package/vitest.config.live.ts +10 -9
- package/vitest.config.ts +29 -17
- package/app/client/README.md +0 -69
- package/app/client/SIMPLIFICATION.md +0 -140
- package/app/client/frontend-only.ts +0 -12
- package/app/client/src/live/FileUploadExample.tsx +0 -359
- package/app/client/src/live/MinimalLiveClock.tsx +0 -47
- package/app/client/src/live/QuickUploadTest.tsx +0 -193
- package/app/client/tsconfig.app.json +0 -45
- package/app/client/tsconfig.json +0 -7
- package/app/client/zustand-setup.md +0 -65
- package/app/server/backend-only.ts +0 -18
- package/app/server/live/LiveClockComponent.ts +0 -215
- package/app/server/live/LiveFileUploadComponent.ts +0 -77
- package/app/server/routes/env-test.ts +0 -110
- package/core/client/hooks/index.ts +0 -7
- package/core/client/hooks/useHybridLiveComponent.ts +0 -685
- package/core/client/hooks/useTypedLiveComponent.ts +0 -133
- package/core/client/hooks/useWebSocket.ts +0 -361
- package/core/config/env.ts +0 -546
- package/core/config/loader.ts +0 -522
- package/core/config/runtime-config.ts +0 -327
- package/core/config/validator.ts +0 -540
- package/core/server/backend-entry.ts +0 -51
- package/core/server/standalone.ts +0 -106
- package/core/utils/regenerate-files.ts +0 -69
- package/fluxstack.config.ts +0 -354
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
// 🚀 Quick Upload Test - Compact upload tester for home page
|
|
2
|
-
import { useState, useRef } from 'react'
|
|
3
|
-
import { useTypedLiveComponent, useChunkedUpload, useLiveComponents } from '@/core/client'
|
|
4
|
-
|
|
5
|
-
// Import component type DIRECTLY from backend - full type inference!
|
|
6
|
-
import type { LiveFileUploadComponent } from '@/server/live/LiveFileUploadComponent'
|
|
7
|
-
|
|
8
|
-
export function QuickUploadTest() {
|
|
9
|
-
const fileInputRef = useRef<HTMLInputElement>(null)
|
|
10
|
-
const [selectedFile, setSelectedFile] = useState<File | null>(null)
|
|
11
|
-
|
|
12
|
-
// Get sendMessageAndWait from LiveComponents context
|
|
13
|
-
const { sendMessageAndWait } = useLiveComponents()
|
|
14
|
-
|
|
15
|
-
// Setup Live Component with full type inference
|
|
16
|
-
const {
|
|
17
|
-
state,
|
|
18
|
-
call,
|
|
19
|
-
componentId,
|
|
20
|
-
connected
|
|
21
|
-
} = useTypedLiveComponent<LiveFileUploadComponent>('LiveFileUpload', {
|
|
22
|
-
uploadedFiles: [],
|
|
23
|
-
maxFiles: 10
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
// Setup Chunked Upload with Adaptive Chunking
|
|
27
|
-
const {
|
|
28
|
-
uploading,
|
|
29
|
-
progress,
|
|
30
|
-
error: uploadError,
|
|
31
|
-
uploadFile,
|
|
32
|
-
cancelUpload,
|
|
33
|
-
reset: resetUpload,
|
|
34
|
-
bytesUploaded,
|
|
35
|
-
totalBytes
|
|
36
|
-
} = useChunkedUpload(componentId || '', {
|
|
37
|
-
chunkSize: 64 * 1024,
|
|
38
|
-
maxFileSize: 500 * 1024 * 1024,
|
|
39
|
-
allowedTypes: [], // Aceita todos os tipos
|
|
40
|
-
sendMessageAndWait,
|
|
41
|
-
|
|
42
|
-
// Enable Adaptive Chunking
|
|
43
|
-
adaptiveChunking: true,
|
|
44
|
-
adaptiveConfig: {
|
|
45
|
-
minChunkSize: 16 * 1024,
|
|
46
|
-
maxChunkSize: 512 * 1024,
|
|
47
|
-
initialChunkSize: 64 * 1024,
|
|
48
|
-
targetLatency: 200,
|
|
49
|
-
adjustmentFactor: 1.5,
|
|
50
|
-
measurementWindow: 3
|
|
51
|
-
},
|
|
52
|
-
|
|
53
|
-
onComplete: async (response) => {
|
|
54
|
-
if (selectedFile && response.fileUrl) {
|
|
55
|
-
await call('onFileUploaded', {
|
|
56
|
-
filename: selectedFile.name,
|
|
57
|
-
fileUrl: response.fileUrl
|
|
58
|
-
})
|
|
59
|
-
}
|
|
60
|
-
setSelectedFile(null)
|
|
61
|
-
resetUpload()
|
|
62
|
-
if (fileInputRef.current) {
|
|
63
|
-
fileInputRef.current.value = ''
|
|
64
|
-
}
|
|
65
|
-
},
|
|
66
|
-
|
|
67
|
-
onError: (error) => {
|
|
68
|
-
console.error('Upload error:', error)
|
|
69
|
-
}
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
73
|
-
const file = e.target.files?.[0]
|
|
74
|
-
if (file) {
|
|
75
|
-
setSelectedFile(file)
|
|
76
|
-
resetUpload()
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const handleUpload = async () => {
|
|
81
|
-
if (!selectedFile) return
|
|
82
|
-
await uploadFile(selectedFile)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const formatBytes = (bytes: number): string => {
|
|
86
|
-
if (bytes === 0) return '0 B'
|
|
87
|
-
const k = 1024
|
|
88
|
-
const sizes = ['B', 'KB', 'MB']
|
|
89
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
|
90
|
-
return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i]
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (!connected) {
|
|
94
|
-
return (
|
|
95
|
-
<div className="bg-white/5 backdrop-blur-sm border border-white/10 rounded-2xl p-6">
|
|
96
|
-
<div className="text-yellow-400 text-sm">🔌 Connecting...</div>
|
|
97
|
-
</div>
|
|
98
|
-
)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return (
|
|
102
|
-
<div className="bg-white/5 backdrop-blur-sm border border-white/10 rounded-2xl p-6 hover:bg-white/10 transition-all">
|
|
103
|
-
<div className="flex items-center gap-3 mb-4">
|
|
104
|
-
<div className="text-3xl">📤</div>
|
|
105
|
-
<div>
|
|
106
|
-
<h3 className="text-lg font-semibold text-white">Adaptive Upload Test</h3>
|
|
107
|
-
<p className="text-xs text-gray-400">Dynamic chunk sizing enabled</p>
|
|
108
|
-
</div>
|
|
109
|
-
</div>
|
|
110
|
-
|
|
111
|
-
{/* File Input */}
|
|
112
|
-
<div className="space-y-3">
|
|
113
|
-
<input
|
|
114
|
-
ref={fileInputRef}
|
|
115
|
-
type="file"
|
|
116
|
-
onChange={handleFileSelect}
|
|
117
|
-
disabled={uploading}
|
|
118
|
-
className="block w-full text-sm text-gray-300 file:mr-3 file:py-2 file:px-4 file:rounded-lg file:border-0 file:text-sm file:font-semibold file:bg-purple-600 file:text-white hover:file:bg-purple-700 disabled:opacity-50 cursor-pointer"
|
|
119
|
-
/>
|
|
120
|
-
|
|
121
|
-
{/* Selected File */}
|
|
122
|
-
{selectedFile && !uploading && (
|
|
123
|
-
<div className="text-sm text-gray-300">
|
|
124
|
-
📁 {selectedFile.name} ({formatBytes(selectedFile.size)})
|
|
125
|
-
</div>
|
|
126
|
-
)}
|
|
127
|
-
|
|
128
|
-
{/* Upload Progress */}
|
|
129
|
-
{uploading && (
|
|
130
|
-
<div className="space-y-2">
|
|
131
|
-
<div className="flex justify-between text-xs text-gray-300">
|
|
132
|
-
<span>Uploading...</span>
|
|
133
|
-
<span>{progress.toFixed(1)}%</span>
|
|
134
|
-
</div>
|
|
135
|
-
<div className="w-full bg-gray-700 rounded-full h-2">
|
|
136
|
-
<div
|
|
137
|
-
className="bg-gradient-to-r from-blue-500 to-purple-600 h-2 rounded-full transition-all duration-300"
|
|
138
|
-
style={{ width: `${progress}%` }}
|
|
139
|
-
/>
|
|
140
|
-
</div>
|
|
141
|
-
<div className="text-xs text-gray-400">
|
|
142
|
-
{formatBytes(bytesUploaded)} / {formatBytes(totalBytes)}
|
|
143
|
-
</div>
|
|
144
|
-
</div>
|
|
145
|
-
)}
|
|
146
|
-
|
|
147
|
-
{/* Error */}
|
|
148
|
-
{uploadError && (
|
|
149
|
-
<div className="text-xs text-red-400">❌ {uploadError}</div>
|
|
150
|
-
)}
|
|
151
|
-
|
|
152
|
-
{/* Buttons */}
|
|
153
|
-
<div className="flex gap-2">
|
|
154
|
-
<button
|
|
155
|
-
onClick={handleUpload}
|
|
156
|
-
disabled={!selectedFile || uploading}
|
|
157
|
-
className="flex-1 px-4 py-2 bg-gradient-to-r from-blue-500 to-purple-600 text-white rounded-lg hover:shadow-lg hover:shadow-purple-500/50 disabled:opacity-50 disabled:cursor-not-allowed font-medium text-sm transition-all"
|
|
158
|
-
>
|
|
159
|
-
{uploading ? '⏳ Uploading...' : '🚀 Upload'}
|
|
160
|
-
</button>
|
|
161
|
-
|
|
162
|
-
{uploading && (
|
|
163
|
-
<button
|
|
164
|
-
onClick={cancelUpload}
|
|
165
|
-
className="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 font-medium text-sm"
|
|
166
|
-
>
|
|
167
|
-
❌
|
|
168
|
-
</button>
|
|
169
|
-
)}
|
|
170
|
-
</div>
|
|
171
|
-
|
|
172
|
-
{/* Last Upload Info */}
|
|
173
|
-
{state.uploadedFiles.length > 0 && !uploading && (
|
|
174
|
-
<div className="pt-3 border-t border-white/10">
|
|
175
|
-
<div className="text-xs text-green-400">
|
|
176
|
-
✅ Last: {state.uploadedFiles[0].filename}
|
|
177
|
-
</div>
|
|
178
|
-
</div>
|
|
179
|
-
)}
|
|
180
|
-
|
|
181
|
-
{/* Quick Stats */}
|
|
182
|
-
<div className="pt-3 border-t border-white/10">
|
|
183
|
-
<div className="text-xs text-gray-400 space-y-1">
|
|
184
|
-
<div>🚀 Adaptive: 16KB - 512KB</div>
|
|
185
|
-
<div>📊 Target: 200ms/chunk</div>
|
|
186
|
-
<div>💾 Max: 500MB</div>
|
|
187
|
-
<div>📁 All file types</div>
|
|
188
|
-
</div>
|
|
189
|
-
</div>
|
|
190
|
-
</div>
|
|
191
|
-
</div>
|
|
192
|
-
)
|
|
193
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
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
|
-
"skipLibCheck": true,
|
|
9
|
-
|
|
10
|
-
/* Bundler mode */
|
|
11
|
-
"moduleResolution": "bundler",
|
|
12
|
-
"allowImportingTsExtensions": true,
|
|
13
|
-
"verbatimModuleSyntax": true,
|
|
14
|
-
"moduleDetection": "force",
|
|
15
|
-
"noEmit": true,
|
|
16
|
-
"jsx": "react-jsx",
|
|
17
|
-
|
|
18
|
-
/* Path mapping (alias support) */
|
|
19
|
-
"baseUrl": ".",
|
|
20
|
-
"paths": {
|
|
21
|
-
"@/*": ["./src/*"],
|
|
22
|
-
"@/components/*": ["./src/components/*"],
|
|
23
|
-
"@/utils/*": ["./src/utils/*"],
|
|
24
|
-
"@/hooks/*": ["./src/hooks/*"],
|
|
25
|
-
"@/assets/*": ["./src/assets/*"],
|
|
26
|
-
"@/lib/*": ["./src/lib/*"],
|
|
27
|
-
"@/types/*": ["./src/types/*"],
|
|
28
|
-
"@/shared/*": ["../shared/*"],
|
|
29
|
-
"@/server/*": ["../server/*"],
|
|
30
|
-
"@/core/*": ["../../core/*"],
|
|
31
|
-
"@/config/*": ["../../config/*"],
|
|
32
|
-
"fluxstack": ["../../core/client/fluxstack"],
|
|
33
|
-
"elysia": ["../../node_modules/elysia"]
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
-
/* Linting */
|
|
37
|
-
"strict": true,
|
|
38
|
-
"noUnusedLocals": true,
|
|
39
|
-
"noUnusedParameters": true,
|
|
40
|
-
"erasableSyntaxOnly": true,
|
|
41
|
-
"noFallthroughCasesInSwitch": true,
|
|
42
|
-
"noUncheckedSideEffectImports": true
|
|
43
|
-
},
|
|
44
|
-
"include": ["src"]
|
|
45
|
-
}
|
package/app/client/tsconfig.json
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
# Zustand Setup for FluxStack
|
|
2
|
-
|
|
3
|
-
## Installation
|
|
4
|
-
|
|
5
|
-
Add Zustand to your project:
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
# Using npm
|
|
9
|
-
npm install zustand
|
|
10
|
-
|
|
11
|
-
# Using yarn
|
|
12
|
-
yarn add zustand
|
|
13
|
-
|
|
14
|
-
# Using pnpm
|
|
15
|
-
pnpm add zustand
|
|
16
|
-
|
|
17
|
-
# Using bun
|
|
18
|
-
bun add zustand
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## Package.json Dependencies
|
|
22
|
-
|
|
23
|
-
Add to your `package.json`:
|
|
24
|
-
|
|
25
|
-
```json
|
|
26
|
-
{
|
|
27
|
-
"dependencies": {
|
|
28
|
-
"zustand": "^4.4.7"
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## TypeScript Support
|
|
34
|
-
|
|
35
|
-
Zustand has built-in TypeScript support, no additional packages needed.
|
|
36
|
-
|
|
37
|
-
## Optional: DevTools Integration
|
|
38
|
-
|
|
39
|
-
For Redux DevTools integration (already included in our stores):
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
# No additional packages needed - works out of the box
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Middleware
|
|
46
|
-
|
|
47
|
-
Our stores already use the `persist` middleware. Other useful middleware:
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
# For more advanced middleware (optional)
|
|
51
|
-
npm install immer # For immutable updates
|
|
52
|
-
npm install zustand-middleware-yjs # For collaborative editing
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## Ready to Use
|
|
56
|
-
|
|
57
|
-
The FluxStack template already includes:
|
|
58
|
-
- ✅ User authentication store
|
|
59
|
-
- ✅ UI state store
|
|
60
|
-
- ✅ Persistence middleware
|
|
61
|
-
- ✅ DevTools integration
|
|
62
|
-
- ✅ Utility hooks
|
|
63
|
-
- ✅ TypeScript support
|
|
64
|
-
|
|
65
|
-
Just start using the stores in your components!
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Backend Standalone Entry Point
|
|
3
|
-
*
|
|
4
|
-
* This is a minimal wrapper for starting the backend in standalone mode.
|
|
5
|
-
* The core logic is protected in @/core/server/backend-entry.ts
|
|
6
|
-
*
|
|
7
|
-
* You can customize the configuration here if needed.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { startBackend, createBackendConfig } from "@/core/server/backend-entry"
|
|
11
|
-
import { appInstance } from "./app"
|
|
12
|
-
import { serverConfig } from "@/config/server.config"
|
|
13
|
-
|
|
14
|
-
// Create backend configuration from declarative config
|
|
15
|
-
const backendConfig = createBackendConfig(serverConfig)
|
|
16
|
-
|
|
17
|
-
// Start backend in standalone mode
|
|
18
|
-
startBackend(appInstance, backendConfig)
|
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
// 🔥 LiveClock - Real-time Clock Live Component
|
|
2
|
-
// Automatically updates every second and broadcasts to all connected clients
|
|
3
|
-
import { LiveComponent } from "@/core/types/types";
|
|
4
|
-
|
|
5
|
-
interface LiveClockState {
|
|
6
|
-
currentTime: string; // Formatted time string
|
|
7
|
-
timeZone: string; // IANA timezone (e.g., 'America/Sao_Paulo')
|
|
8
|
-
format: '12h' | '24h'; // Time format preference
|
|
9
|
-
showSeconds: boolean; // Toggle seconds display
|
|
10
|
-
showDate: boolean; // Toggle date display
|
|
11
|
-
lastSync: Date; // Last sync timestamp
|
|
12
|
-
serverUptime: number; // Server uptime in seconds
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export class LiveClockComponent extends LiveComponent<LiveClockState> {
|
|
16
|
-
private clockInterval: NodeJS.Timeout | null = null;
|
|
17
|
-
private startTime: Date;
|
|
18
|
-
|
|
19
|
-
constructor(initialState: LiveClockState, ws: any, options?: { room?: string; userId?: string }) {
|
|
20
|
-
const now = new Date();
|
|
21
|
-
super({
|
|
22
|
-
currentTime: now.toLocaleTimeString('pt-BR'),
|
|
23
|
-
timeZone: 'America/Sao_Paulo',
|
|
24
|
-
format: '24h',
|
|
25
|
-
showSeconds: true,
|
|
26
|
-
showDate: true,
|
|
27
|
-
lastSync: now,
|
|
28
|
-
serverUptime: 0,
|
|
29
|
-
...initialState
|
|
30
|
-
}, ws, options);
|
|
31
|
-
|
|
32
|
-
this.startTime = now;
|
|
33
|
-
console.log(`🕐 ${this.constructor.name} created: ${this.id}`);
|
|
34
|
-
|
|
35
|
-
// Start the real-time clock immediately
|
|
36
|
-
this.startClock();
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
private startClock() {
|
|
40
|
-
// Clear any existing interval
|
|
41
|
-
if (this.clockInterval) {
|
|
42
|
-
clearInterval(this.clockInterval);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Update clock every second
|
|
46
|
-
this.clockInterval = setInterval(() => {
|
|
47
|
-
this.updateClock();
|
|
48
|
-
}, 1000);
|
|
49
|
-
|
|
50
|
-
// Initial update
|
|
51
|
-
this.updateClock();
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
private updateClock() {
|
|
55
|
-
const now = new Date();
|
|
56
|
-
const uptimeMs = now.getTime() - this.startTime.getTime();
|
|
57
|
-
|
|
58
|
-
let timeString;
|
|
59
|
-
if (this.state.format === '12h') {
|
|
60
|
-
timeString = now.toLocaleTimeString('en-US', {
|
|
61
|
-
hour12: true,
|
|
62
|
-
hour: 'numeric',
|
|
63
|
-
minute: '2-digit',
|
|
64
|
-
second: this.state.showSeconds ? '2-digit' : undefined
|
|
65
|
-
});
|
|
66
|
-
} else {
|
|
67
|
-
timeString = now.toLocaleTimeString('pt-BR', {
|
|
68
|
-
hour12: false,
|
|
69
|
-
hour: '2-digit',
|
|
70
|
-
minute: '2-digit',
|
|
71
|
-
second: this.state.showSeconds ? '2-digit' : undefined
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
this.setState({
|
|
76
|
-
currentTime: timeString,
|
|
77
|
-
lastSync: now,
|
|
78
|
-
serverUptime: Math.floor(uptimeMs / 1000)
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
// Broadcast time update to all connected clients
|
|
82
|
-
if (this.room) {
|
|
83
|
-
this.broadcast('CLOCK_TICK', {
|
|
84
|
-
currentTime: timeString,
|
|
85
|
-
timestamp: now.toISOString(),
|
|
86
|
-
serverUptime: Math.floor(uptimeMs / 1000)
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
async setTimeFormat(payload: { format: '12h' | '24h' }) {
|
|
92
|
-
const { format } = payload;
|
|
93
|
-
|
|
94
|
-
if (format !== '12h' && format !== '24h') {
|
|
95
|
-
throw new Error('Invalid time format. Use "12h" or "24h"');
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
this.setState({
|
|
99
|
-
format,
|
|
100
|
-
lastSync: new Date()
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
// Immediately update the clock display with new format
|
|
104
|
-
this.updateClock();
|
|
105
|
-
|
|
106
|
-
console.log(`🕐 Time format changed to: ${format}`);
|
|
107
|
-
return { success: true, format };
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
async toggleSeconds(payload?: { showSeconds?: boolean }) {
|
|
111
|
-
const showSeconds = payload?.showSeconds ?? !this.state.showSeconds;
|
|
112
|
-
|
|
113
|
-
this.setState({
|
|
114
|
-
showSeconds,
|
|
115
|
-
lastSync: new Date()
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
// Update clock display immediately
|
|
119
|
-
this.updateClock();
|
|
120
|
-
|
|
121
|
-
console.log(`🕐 Seconds display: ${showSeconds ? 'ON' : 'OFF'}`);
|
|
122
|
-
return { success: true, showSeconds };
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
async toggleDate(payload?: { showDate?: boolean }) {
|
|
126
|
-
const showDate = payload?.showDate ?? !this.state.showDate;
|
|
127
|
-
|
|
128
|
-
this.setState({
|
|
129
|
-
showDate,
|
|
130
|
-
lastSync: new Date()
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
console.log(`🕐 Date display: ${showDate ? 'ON' : 'OFF'}`);
|
|
134
|
-
return { success: true, showDate };
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
async setTimeZone(payload: { timeZone: string }) {
|
|
138
|
-
const { timeZone } = payload;
|
|
139
|
-
|
|
140
|
-
// Basic timezone validation
|
|
141
|
-
try {
|
|
142
|
-
new Date().toLocaleString('en-US', { timeZone });
|
|
143
|
-
} catch (error) {
|
|
144
|
-
throw new Error(`Invalid timezone: ${timeZone}`);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
this.setState({
|
|
148
|
-
timeZone,
|
|
149
|
-
lastSync: new Date()
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
console.log(`🕐 Timezone changed to: ${timeZone}`);
|
|
153
|
-
return { success: true, timeZone };
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
async getServerInfo() {
|
|
157
|
-
console.log(`🕐 getServerInfo called for component: ${this.id}`);
|
|
158
|
-
|
|
159
|
-
const now = new Date();
|
|
160
|
-
const uptimeMs = now.getTime() - this.startTime.getTime();
|
|
161
|
-
|
|
162
|
-
const result = {
|
|
163
|
-
success: true,
|
|
164
|
-
info: {
|
|
165
|
-
serverTime: now.toISOString(),
|
|
166
|
-
localTime: now.toLocaleString('pt-BR'),
|
|
167
|
-
uptime: Math.floor(uptimeMs / 1000),
|
|
168
|
-
uptimeFormatted: this.formatUptime(Math.floor(uptimeMs / 1000)),
|
|
169
|
-
timezone: this.state.timeZone,
|
|
170
|
-
componentId: this.id,
|
|
171
|
-
startTime: this.startTime.toISOString()
|
|
172
|
-
}
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
console.log(`🕐 getServerInfo result:`, result);
|
|
176
|
-
return result;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
async syncTime() {
|
|
180
|
-
// Force a manual time sync
|
|
181
|
-
this.updateClock();
|
|
182
|
-
|
|
183
|
-
console.log(`🕐 Manual time sync performed`);
|
|
184
|
-
return {
|
|
185
|
-
success: true,
|
|
186
|
-
syncTime: new Date().toISOString(),
|
|
187
|
-
currentTime: this.state.currentTime
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
private formatUptime(seconds: number): string {
|
|
192
|
-
const hours = Math.floor(seconds / 3600);
|
|
193
|
-
const minutes = Math.floor((seconds % 3600) / 60);
|
|
194
|
-
const secs = seconds % 60;
|
|
195
|
-
|
|
196
|
-
if (hours > 0) {
|
|
197
|
-
return `${hours}h ${minutes}m ${secs}s`;
|
|
198
|
-
} else if (minutes > 0) {
|
|
199
|
-
return `${minutes}m ${secs}s`;
|
|
200
|
-
} else {
|
|
201
|
-
return `${secs}s`;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
public destroy() {
|
|
206
|
-
// Clean up the interval when component is destroyed
|
|
207
|
-
if (this.clockInterval) {
|
|
208
|
-
clearInterval(this.clockInterval);
|
|
209
|
-
this.clockInterval = null;
|
|
210
|
-
console.log(`🕐 Clock interval cleared for component: ${this.id}`);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
super.destroy();
|
|
214
|
-
}
|
|
215
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
// 📤 Live File Upload Component - Universal file upload with chunking
|
|
2
|
-
import { LiveComponent } from '@/core/types/types'
|
|
3
|
-
|
|
4
|
-
interface FileUploadState {
|
|
5
|
-
uploadedFiles: Array<{
|
|
6
|
-
id: string
|
|
7
|
-
filename: string
|
|
8
|
-
url: string
|
|
9
|
-
uploadedAt: number
|
|
10
|
-
}>
|
|
11
|
-
maxFiles: number
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export class LiveFileUploadComponent extends LiveComponent<FileUploadState> {
|
|
15
|
-
constructor(initialState: FileUploadState, ws: any, options?: { room?: string; userId?: string }) {
|
|
16
|
-
super({
|
|
17
|
-
uploadedFiles: [],
|
|
18
|
-
maxFiles: 10,
|
|
19
|
-
...initialState
|
|
20
|
-
}, ws, options)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Handle successful file upload
|
|
25
|
-
* This is called from the client after useChunkedUpload completes
|
|
26
|
-
*/
|
|
27
|
-
async onFileUploaded(payload: { filename: string; fileUrl: string }): Promise<void> {
|
|
28
|
-
const { filename, fileUrl } = payload
|
|
29
|
-
|
|
30
|
-
// Add new file to the list
|
|
31
|
-
const newFile = {
|
|
32
|
-
id: `file-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
33
|
-
filename,
|
|
34
|
-
url: fileUrl,
|
|
35
|
-
uploadedAt: Date.now()
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Limit to maxFiles
|
|
39
|
-
const updatedFiles = [newFile, ...this.state.uploadedFiles].slice(0, this.state.maxFiles)
|
|
40
|
-
|
|
41
|
-
// Update state and broadcast to all clients
|
|
42
|
-
this.setState({
|
|
43
|
-
uploadedFiles: updatedFiles
|
|
44
|
-
})
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Remove an uploaded file
|
|
49
|
-
*/
|
|
50
|
-
async removeFile(payload: { fileId: string }): Promise<void> {
|
|
51
|
-
this.setState({
|
|
52
|
-
uploadedFiles: this.state.uploadedFiles.filter(file => file.id !== payload.fileId)
|
|
53
|
-
})
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Clear all uploaded files
|
|
58
|
-
*/
|
|
59
|
-
async clearAll(): Promise<void> {
|
|
60
|
-
this.setState({
|
|
61
|
-
uploadedFiles: []
|
|
62
|
-
})
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Get upload statistics
|
|
67
|
-
*/
|
|
68
|
-
async getStats(): Promise<{
|
|
69
|
-
totalFiles: number
|
|
70
|
-
remainingSlots: number
|
|
71
|
-
}> {
|
|
72
|
-
return {
|
|
73
|
-
totalFiles: this.state.uploadedFiles.length,
|
|
74
|
-
remainingSlots: this.state.maxFiles - this.state.uploadedFiles.length
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|