create-fluxstack 1.12.1 → 1.14.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/LLMD/INDEX.md +8 -1
- package/LLMD/agent.md +867 -0
- package/LLMD/config/environment-vars.md +30 -0
- package/LLMD/patterns/anti-patterns.md +100 -0
- package/LLMD/reference/routing.md +39 -39
- package/LLMD/resources/live-auth.md +465 -0
- package/LLMD/resources/live-components.md +168 -26
- package/LLMD/resources/live-logging.md +220 -0
- package/LLMD/resources/live-upload.md +59 -8
- package/LLMD/resources/rest-auth.md +290 -0
- package/README.md +520 -340
- package/app/client/index.html +2 -2
- package/app/client/public/favicon.svg +46 -0
- package/app/client/src/App.tsx +13 -1
- package/app/client/src/assets/fluxstack-static.svg +46 -0
- package/app/client/src/assets/fluxstack.svg +183 -0
- package/app/client/src/components/AppLayout.tsx +139 -9
- package/app/client/src/components/BackButton.tsx +13 -13
- package/app/client/src/components/DemoPage.tsx +4 -4
- package/app/client/src/live/AuthDemo.tsx +334 -0
- package/app/client/src/live/ChatDemo.tsx +2 -2
- package/app/client/src/live/CounterDemo.tsx +12 -12
- package/app/client/src/live/FormDemo.tsx +2 -2
- package/app/client/src/live/LiveDebuggerPanel.tsx +779 -0
- package/app/client/src/live/RoomChatDemo.tsx +24 -16
- package/app/client/src/main.tsx +13 -13
- package/app/client/src/pages/ApiTestPage.tsx +6 -6
- package/app/client/src/pages/HomePage.tsx +80 -52
- package/app/server/auth/AuthManager.ts +213 -0
- package/app/server/auth/DevAuthProvider.ts +66 -0
- package/app/server/auth/HashManager.ts +123 -0
- package/app/server/auth/JWTAuthProvider.example.ts +101 -0
- package/app/server/auth/RateLimiter.ts +106 -0
- package/app/server/auth/contracts.ts +192 -0
- package/app/server/auth/guards/SessionGuard.ts +167 -0
- package/app/server/auth/guards/TokenGuard.ts +202 -0
- package/app/server/auth/index.ts +174 -0
- package/app/server/auth/middleware.ts +163 -0
- package/app/server/auth/providers/InMemoryProvider.ts +162 -0
- package/app/server/auth/sessions/SessionManager.ts +164 -0
- package/app/server/cache/CacheManager.ts +81 -0
- package/app/server/cache/MemoryDriver.ts +112 -0
- package/app/server/cache/contracts.ts +49 -0
- package/app/server/cache/index.ts +42 -0
- package/app/server/index.ts +14 -0
- package/app/server/live/LiveAdminPanel.ts +174 -0
- package/app/server/live/LiveChat.ts +78 -77
- package/app/server/live/LiveCounter.ts +1 -0
- package/app/server/live/LiveForm.ts +1 -0
- package/app/server/live/LiveLocalCounter.ts +38 -32
- package/app/server/live/LiveProtectedChat.ts +151 -0
- package/app/server/live/LiveRoomChat.ts +1 -0
- package/app/server/live/LiveUpload.ts +1 -0
- package/app/server/live/register-components.ts +19 -19
- package/app/server/routes/auth.routes.ts +278 -0
- package/app/server/routes/index.ts +2 -0
- package/config/index.ts +8 -0
- package/config/system/auth.config.ts +49 -0
- package/config/system/runtime.config.ts +4 -0
- package/config/system/session.config.ts +33 -0
- package/core/build/optimizer.ts +235 -235
- package/core/client/LiveComponentsProvider.tsx +76 -5
- package/core/client/components/Live.tsx +17 -10
- package/core/client/components/LiveDebugger.tsx +1324 -0
- package/core/client/hooks/AdaptiveChunkSizer.ts +215 -215
- package/core/client/hooks/useLiveComponent.ts +58 -5
- package/core/client/hooks/useLiveDebugger.ts +392 -0
- package/core/client/index.ts +16 -1
- package/core/framework/server.ts +36 -4
- package/core/plugins/built-in/index.ts +134 -134
- package/core/plugins/built-in/live-components/commands/create-live-component.ts +19 -8
- package/core/plugins/built-in/monitoring/index.ts +10 -3
- package/core/plugins/built-in/vite/index.ts +151 -20
- package/core/plugins/config.ts +5 -4
- package/core/plugins/discovery.ts +11 -2
- package/core/plugins/manager.ts +11 -5
- package/core/plugins/module-resolver.ts +1 -1
- package/core/plugins/registry.ts +53 -25
- package/core/server/index.ts +15 -15
- package/core/server/live/ComponentRegistry.ts +134 -50
- package/core/server/live/FileUploadManager.ts +188 -24
- package/core/server/live/LiveComponentPerformanceMonitor.ts +9 -8
- package/core/server/live/LiveDebugger.ts +462 -0
- package/core/server/live/LiveLogger.ts +144 -0
- package/core/server/live/LiveRoomManager.ts +22 -5
- package/core/server/live/StateSignature.ts +704 -643
- package/core/server/live/WebSocketConnectionManager.ts +11 -10
- package/core/server/live/auth/LiveAuthContext.ts +71 -0
- package/core/server/live/auth/LiveAuthManager.ts +304 -0
- package/core/server/live/auth/index.ts +19 -0
- package/core/server/live/auth/types.ts +179 -0
- package/core/server/live/auto-generated-components.ts +8 -2
- package/core/server/live/index.ts +16 -0
- package/core/server/live/websocket-plugin.ts +323 -22
- package/core/server/plugins/static-files-plugin.ts +179 -69
- package/core/templates/create-project.ts +0 -3
- package/core/types/build.ts +219 -219
- package/core/types/plugin.ts +107 -107
- package/core/types/types.ts +278 -22
- package/core/utils/index.ts +17 -17
- package/core/utils/logger/index.ts +5 -2
- package/core/utils/logger/startup-banner.ts +82 -82
- package/core/utils/version.ts +6 -6
- package/package.json +1 -8
- package/plugins/crypto-auth/index.ts +6 -0
- package/plugins/crypto-auth/server/CryptoAuthLiveProvider.ts +58 -0
- package/plugins/crypto-auth/server/index.ts +24 -21
- package/rest-tests/README.md +57 -0
- package/rest-tests/auth-token.http +113 -0
- package/rest-tests/auth.http +112 -0
- package/rest-tests/rooms-token.http +69 -0
- package/rest-tests/users-token.http +62 -0
- package/.dockerignore +0 -81
- package/Dockerfile +0 -70
- package/LIVE_COMPONENTS_REVIEW.md +0 -781
- package/app/client/src/assets/react.svg +0 -1
|
@@ -1,77 +1,78 @@
|
|
|
1
|
-
// LiveChat - Chat compartilhado por sala
|
|
2
|
-
|
|
3
|
-
import { LiveComponent, type FluxStackWebSocket } from '@core/types/types'
|
|
4
|
-
|
|
5
|
-
// Componente Cliente (Ctrl+Click para navegar)
|
|
6
|
-
import type { ChatDemo as _Client } from '@client/src/live/ChatDemo'
|
|
7
|
-
|
|
8
|
-
export type ChatMessage = {
|
|
9
|
-
id: string
|
|
10
|
-
user: string
|
|
11
|
-
text: string
|
|
12
|
-
timestamp: number
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export class LiveChat extends LiveComponent<typeof LiveChat.defaultState> {
|
|
16
|
-
static componentName = 'LiveChat'
|
|
17
|
-
static
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
private
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
1
|
+
// LiveChat - Chat compartilhado por sala
|
|
2
|
+
|
|
3
|
+
import { LiveComponent, type FluxStackWebSocket } from '@core/types/types'
|
|
4
|
+
|
|
5
|
+
// Componente Cliente (Ctrl+Click para navegar)
|
|
6
|
+
import type { ChatDemo as _Client } from '@client/src/live/ChatDemo'
|
|
7
|
+
|
|
8
|
+
export type ChatMessage = {
|
|
9
|
+
id: string
|
|
10
|
+
user: string
|
|
11
|
+
text: string
|
|
12
|
+
timestamp: number
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class LiveChat extends LiveComponent<typeof LiveChat.defaultState> {
|
|
16
|
+
static componentName = 'LiveChat'
|
|
17
|
+
static publicActions = ['sendMessage'] as const
|
|
18
|
+
static defaultState = {
|
|
19
|
+
messages: [] as ChatMessage[]
|
|
20
|
+
}
|
|
21
|
+
protected roomType = 'chat'
|
|
22
|
+
private maxMessages = 50
|
|
23
|
+
private static roomHistory = new Map<string, ChatMessage[]>()
|
|
24
|
+
|
|
25
|
+
constructor(initialState: Partial<typeof LiveChat.defaultState> = {}, ws: FluxStackWebSocket, options?: { room?: string; userId?: string }) {
|
|
26
|
+
super(initialState, ws, options)
|
|
27
|
+
|
|
28
|
+
this.onRoomEvent<ChatMessage>('NEW_MESSAGE', (message) => {
|
|
29
|
+
this.addMessage(message)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
if (this.room) {
|
|
33
|
+
const history = LiveChat.roomHistory.get(this.room) || []
|
|
34
|
+
if (history.length > 0) {
|
|
35
|
+
this.setState({ messages: history })
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private addMessage(message: ChatMessage) {
|
|
41
|
+
const next = [...this.state.messages, message].slice(-this.maxMessages)
|
|
42
|
+
if (this.room) {
|
|
43
|
+
LiveChat.roomHistory.set(this.room, next)
|
|
44
|
+
}
|
|
45
|
+
this.setState({ messages: next })
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async sendMessage(payload: { user: string; text: string }) {
|
|
49
|
+
const text = payload.text?.trim()
|
|
50
|
+
const user = payload.user?.trim() || 'anonymous'
|
|
51
|
+
|
|
52
|
+
if (!text) {
|
|
53
|
+
throw new Error('Message cannot be empty')
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (text.length > 500) {
|
|
57
|
+
throw new Error('Message too long')
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const message: ChatMessage = {
|
|
61
|
+
id: `msg-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
62
|
+
user,
|
|
63
|
+
text,
|
|
64
|
+
timestamp: Date.now()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const next = [...this.state.messages, message].slice(-this.maxMessages)
|
|
68
|
+
if (this.room) {
|
|
69
|
+
LiveChat.roomHistory.set(this.room, next)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
this.emitRoomEventWithState('NEW_MESSAGE', message, {
|
|
73
|
+
messages: next
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
return { success: true }
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -7,6 +7,7 @@ import type { CounterDemo as _Client } from '@client/src/live/CounterDemo'
|
|
|
7
7
|
|
|
8
8
|
export class LiveCounter extends LiveComponent<typeof LiveCounter.defaultState> {
|
|
9
9
|
static componentName = 'LiveCounter'
|
|
10
|
+
static publicActions = ['increment', 'decrement', 'reset'] as const
|
|
10
11
|
static defaultState = {
|
|
11
12
|
count: 0,
|
|
12
13
|
lastUpdatedBy: null as string | null,
|
|
@@ -7,6 +7,7 @@ import type { FormDemo as _Client } from '@client/src/live/FormDemo'
|
|
|
7
7
|
|
|
8
8
|
export class LiveForm extends LiveComponent<typeof LiveForm.defaultState> {
|
|
9
9
|
static componentName = 'LiveForm'
|
|
10
|
+
static publicActions = ['submit', 'reset', 'validate', 'setValue'] as const
|
|
10
11
|
static defaultState = {
|
|
11
12
|
name: '',
|
|
12
13
|
email: '',
|
|
@@ -1,32 +1,38 @@
|
|
|
1
|
-
// LiveLocalCounter - Contador sem eventos de sala
|
|
2
|
-
|
|
3
|
-
import { LiveComponent } from '@core/types/types'
|
|
4
|
-
|
|
5
|
-
// Componente Cliente (Ctrl+Click para navegar)
|
|
6
|
-
import type { CounterDemo as _Client } from '@client/src/live/CounterDemo'
|
|
7
|
-
|
|
8
|
-
export class LiveLocalCounter extends LiveComponent<typeof LiveLocalCounter.defaultState> {
|
|
9
|
-
static componentName = 'LiveLocalCounter'
|
|
10
|
-
static
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
async
|
|
22
|
-
this.
|
|
23
|
-
this.
|
|
24
|
-
return { success: true, count: this.
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async
|
|
28
|
-
this.
|
|
29
|
-
this.
|
|
30
|
-
return { success: true, count:
|
|
31
|
-
}
|
|
32
|
-
|
|
1
|
+
// LiveLocalCounter - Contador sem eventos de sala
|
|
2
|
+
|
|
3
|
+
import { LiveComponent } from '@core/types/types'
|
|
4
|
+
|
|
5
|
+
// Componente Cliente (Ctrl+Click para navegar)
|
|
6
|
+
import type { CounterDemo as _Client } from '@client/src/live/CounterDemo'
|
|
7
|
+
|
|
8
|
+
export class LiveLocalCounter extends LiveComponent<typeof LiveLocalCounter.defaultState> {
|
|
9
|
+
static componentName = 'LiveLocalCounter'
|
|
10
|
+
static publicActions = ['increment', 'decrement', 'reset'] as const
|
|
11
|
+
static defaultState = {
|
|
12
|
+
count: 0,
|
|
13
|
+
clicks: 0
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Declarar propriedades (criadas dinamicamente pelo LiveComponent)
|
|
17
|
+
declare count: number
|
|
18
|
+
declare clicks: number
|
|
19
|
+
|
|
20
|
+
// 🔥 Agora usa this.count diretamente!
|
|
21
|
+
async increment() {
|
|
22
|
+
this.count++
|
|
23
|
+
this.clicks++
|
|
24
|
+
return { success: true, count: this.count }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async decrement() {
|
|
28
|
+
this.count--
|
|
29
|
+
this.clicks++
|
|
30
|
+
return { success: true, count: this.count }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async reset() {
|
|
34
|
+
this.count = 0
|
|
35
|
+
this.clicks++
|
|
36
|
+
return { success: true, count: 0 }
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
// 🔒 LiveProtectedChat - Exemplo de Live Component com autenticação
|
|
2
|
+
//
|
|
3
|
+
// Demonstra como usar o sistema de auth em Live Components:
|
|
4
|
+
// - static auth: define que o componente requer autenticação
|
|
5
|
+
// - static actionAuth: define permissões por action
|
|
6
|
+
// - this.$auth: acessa o contexto de auth dentro do componente
|
|
7
|
+
//
|
|
8
|
+
// Client usage:
|
|
9
|
+
// import type { LiveProtectedChat as _Client } from '@client/src/live/ProtectedChat'
|
|
10
|
+
|
|
11
|
+
import { LiveComponent } from '@core/types/types'
|
|
12
|
+
import type { LiveComponentAuth, LiveActionAuthMap } from '@core/server/live/auth/types'
|
|
13
|
+
|
|
14
|
+
interface ChatMessage {
|
|
15
|
+
id: number
|
|
16
|
+
userId: string
|
|
17
|
+
text: string
|
|
18
|
+
timestamp: number
|
|
19
|
+
isAdmin: boolean
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface ProtectedChatState {
|
|
23
|
+
messages: ChatMessage[]
|
|
24
|
+
userCount: number
|
|
25
|
+
currentUser: string | null
|
|
26
|
+
isAdmin: boolean
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export class LiveProtectedChat extends LiveComponent<ProtectedChatState> {
|
|
30
|
+
static componentName = 'LiveProtectedChat'
|
|
31
|
+
static publicActions = ['join', 'sendMessage', 'deleteMessage', 'clearMessages', 'getAuthInfo'] as const
|
|
32
|
+
|
|
33
|
+
static defaultState: ProtectedChatState = {
|
|
34
|
+
messages: [],
|
|
35
|
+
userCount: 0,
|
|
36
|
+
currentUser: null,
|
|
37
|
+
isAdmin: false,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 🔒 Auth: componente requer autenticação
|
|
41
|
+
static auth: LiveComponentAuth = {
|
|
42
|
+
required: true,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// 🔒 Auth por action: deleteMessage requer permissão 'chat.admin'
|
|
46
|
+
static actionAuth: LiveActionAuthMap = {
|
|
47
|
+
deleteMessage: { permissions: ['chat.admin'] },
|
|
48
|
+
clearMessages: { roles: ['admin'] },
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
protected roomType = 'protected-chat'
|
|
52
|
+
|
|
53
|
+
constructor(
|
|
54
|
+
initialState: Partial<ProtectedChatState>,
|
|
55
|
+
ws: any,
|
|
56
|
+
options?: { room?: string; userId?: string }
|
|
57
|
+
) {
|
|
58
|
+
super(initialState, ws, options)
|
|
59
|
+
|
|
60
|
+
// Escutar mensagens de outros usuários na sala
|
|
61
|
+
this.onRoomEvent<ChatMessage>('NEW_MESSAGE', (msg) => {
|
|
62
|
+
const messages = [...this.state.messages, msg].slice(-50)
|
|
63
|
+
this.setState({ messages })
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
this.onRoomEvent<{ count: number }>('USER_COUNT', (data) => {
|
|
67
|
+
this.setState({ userCount: data.count })
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Entra na sala e configura info do usuário autenticado
|
|
73
|
+
*/
|
|
74
|
+
async join(payload: { room: string }) {
|
|
75
|
+
this.$room(payload.room).join()
|
|
76
|
+
|
|
77
|
+
// 🔒 Usar $auth para identificar o usuário
|
|
78
|
+
const userId = this.$auth.user?.id || this.userId || 'anonymous'
|
|
79
|
+
const isAdmin = this.$auth.hasRole('admin')
|
|
80
|
+
|
|
81
|
+
this.setState({
|
|
82
|
+
currentUser: userId,
|
|
83
|
+
isAdmin,
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
return { success: true, userId, isAdmin }
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Envia mensagem - qualquer usuário autenticado pode enviar
|
|
91
|
+
*/
|
|
92
|
+
async sendMessage(payload: { text: string }) {
|
|
93
|
+
if (!payload.text?.trim()) {
|
|
94
|
+
throw new Error('Message cannot be empty')
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const message: ChatMessage = {
|
|
98
|
+
id: Date.now(),
|
|
99
|
+
userId: this.$auth.user?.id || this.userId || 'unknown',
|
|
100
|
+
text: payload.text.trim(),
|
|
101
|
+
timestamp: Date.now(),
|
|
102
|
+
isAdmin: this.$auth.hasRole('admin'),
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Atualiza estado local + notifica outros na sala
|
|
106
|
+
this.emitRoomEventWithState(
|
|
107
|
+
'NEW_MESSAGE',
|
|
108
|
+
message,
|
|
109
|
+
{ messages: [...this.state.messages, message].slice(-50) }
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
return { success: true, messageId: message.id }
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Deleta uma mensagem - requer permissão 'chat.admin'
|
|
117
|
+
* (protegido via static actionAuth)
|
|
118
|
+
*/
|
|
119
|
+
async deleteMessage(payload: { messageId: number }) {
|
|
120
|
+
const messages = this.state.messages.filter(m => m.id !== payload.messageId)
|
|
121
|
+
this.setState({ messages })
|
|
122
|
+
|
|
123
|
+
// Notificar outros na sala
|
|
124
|
+
this.emitRoomEvent('MESSAGE_DELETED', { messageId: payload.messageId })
|
|
125
|
+
|
|
126
|
+
return { success: true }
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Limpa todas as mensagens - requer role 'admin'
|
|
131
|
+
* (protegido via static actionAuth)
|
|
132
|
+
*/
|
|
133
|
+
async clearMessages() {
|
|
134
|
+
this.setState({ messages: [] })
|
|
135
|
+
this.emitRoomEvent('MESSAGES_CLEARED', {})
|
|
136
|
+
return { success: true }
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Retorna info do usuário autenticado (sem restrição extra)
|
|
141
|
+
*/
|
|
142
|
+
async getAuthInfo() {
|
|
143
|
+
return {
|
|
144
|
+
authenticated: this.$auth.authenticated,
|
|
145
|
+
userId: this.$auth.user?.id,
|
|
146
|
+
roles: this.$auth.user?.roles,
|
|
147
|
+
permissions: this.$auth.user?.permissions,
|
|
148
|
+
isAdmin: this.$auth.hasRole('admin'),
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
@@ -14,6 +14,7 @@ export interface ChatMessage {
|
|
|
14
14
|
|
|
15
15
|
export class LiveRoomChat extends LiveComponent<typeof LiveRoomChat.defaultState> {
|
|
16
16
|
static componentName = 'LiveRoomChat'
|
|
17
|
+
static publicActions = ['joinRoom', 'leaveRoom', 'switchRoom', 'sendMessage', 'setUsername'] as const
|
|
17
18
|
static defaultState = {
|
|
18
19
|
username: '',
|
|
19
20
|
activeRoom: null as string | null,
|
|
@@ -7,6 +7,7 @@ import type { UploadDemo as _Client } from '@client/src/live/UploadDemo'
|
|
|
7
7
|
|
|
8
8
|
export class LiveUpload extends LiveComponent<typeof LiveUpload.defaultState> {
|
|
9
9
|
static componentName = 'LiveUpload'
|
|
10
|
+
static publicActions = ['startUpload', 'updateProgress', 'completeUpload', 'failUpload', 'reset'] as const
|
|
10
11
|
static defaultState = {
|
|
11
12
|
status: 'idle' as 'idle' | 'uploading' | 'complete' | 'error',
|
|
12
13
|
progress: 0,
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
// ⚠️ DEPRECATION NOTICE
|
|
2
|
-
// This file has been moved to: core/server/live/auto-generated-components.ts
|
|
3
|
-
//
|
|
4
|
-
// The auto-generated component registration is now located in the core/ directory
|
|
5
|
-
// to prevent accidental user modifications and keep framework code separate from
|
|
6
|
-
// application code.
|
|
7
|
-
//
|
|
8
|
-
// If you're looking for component registration logic:
|
|
9
|
-
// - Generated file: core/server/live/auto-generated-components.ts (auto-generated during build)
|
|
10
|
-
// - Generator: core/build/live-components-generator.ts
|
|
11
|
-
// - Import location: app/server/index.ts
|
|
12
|
-
//
|
|
13
|
-
// To add new Live Components:
|
|
14
|
-
// 1. Create your component class in this directory (app/server/live/)
|
|
15
|
-
// 2. Extend LiveComponent class
|
|
16
|
-
// 3. Run 'bun run build' to regenerate the registration file
|
|
17
|
-
|
|
18
|
-
// This file intentionally left empty - do not import
|
|
19
|
-
export {}
|
|
1
|
+
// ⚠️ DEPRECATION NOTICE
|
|
2
|
+
// This file has been moved to: core/server/live/auto-generated-components.ts
|
|
3
|
+
//
|
|
4
|
+
// The auto-generated component registration is now located in the core/ directory
|
|
5
|
+
// to prevent accidental user modifications and keep framework code separate from
|
|
6
|
+
// application code.
|
|
7
|
+
//
|
|
8
|
+
// If you're looking for component registration logic:
|
|
9
|
+
// - Generated file: core/server/live/auto-generated-components.ts (auto-generated during build)
|
|
10
|
+
// - Generator: core/build/live-components-generator.ts
|
|
11
|
+
// - Import location: app/server/index.ts
|
|
12
|
+
//
|
|
13
|
+
// To add new Live Components:
|
|
14
|
+
// 1. Create your component class in this directory (app/server/live/)
|
|
15
|
+
// 2. Extend LiveComponent class
|
|
16
|
+
// 3. Run 'bun run build' to regenerate the registration file
|
|
17
|
+
|
|
18
|
+
// This file intentionally left empty - do not import
|
|
19
|
+
export {}
|