Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions app/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,18 @@
import { FluxStackFramework } from "@core/server"
import { vitePlugin } from "@core/plugins/built-in/vite"
import { swaggerPlugin } from "@core/plugins/built-in/swagger"
import { liveComponentsPlugin } from "@core/server/live"
import { liveComponentsPlugin, registerAuthProvider } from "@core/server/live"
import { appInstance } from "@server/app"
import { appConfig } from "@config"

// 🔒 Auth provider para Live Components
import { liveAuthManager } from "@core/server/live"
import { DevAuthProvider } from "./auth/DevAuthProvider"

// 🔐 Auth system (Guard + Provider, Laravel-inspired)
import { initAuth } from "@server/auth"

// Registrar provider de desenvolvimento (tokens simples para testes)
liveAuthManager.register(new DevAuthProvider())
registerAuthProvider(new DevAuthProvider())
console.log('🔓 DevAuthProvider registered')

// Inicializar sistema de autenticação
Expand Down
12 changes: 6 additions & 6 deletions app/server/routes/room.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// enviem mensagens para salas de chat via API REST

import { Elysia, t } from 'elysia'
import { liveRoomManager, roomEvents } from '@core/server/live'
import { liveServer } from '@core/server/live'

export const roomRoutes = new Elysia({ prefix: '/rooms' })

Expand All @@ -22,9 +22,9 @@ export const roomRoutes = new Elysia({ prefix: '/rooms' })

// Emitir evento para a sala
// Isso vai:
// 1. Notificar handlers server-side via roomEvents
// 1. Notificar handlers server-side via liveServer!.roomEvents
// 2. Broadcast via WebSocket para frontends
const notified = liveRoomManager.emitToRoom(roomId, 'message:new', message)
const notified = liveServer!.roomManager.emitToRoom(roomId, 'message:new', message)

return {
success: true,
Expand Down Expand Up @@ -63,7 +63,7 @@ export const roomRoutes = new Elysia({ prefix: '/rooms' })
const { roomId } = params
const { event, data } = body

const notified = liveRoomManager.emitToRoom(roomId, event, data)
const notified = liveServer!.roomManager.emitToRoom(roomId, event, data)

return {
success: true,
Expand Down Expand Up @@ -94,8 +94,8 @@ export const roomRoutes = new Elysia({ prefix: '/rooms' })

// Obter estatísticas das salas
.get('/stats', () => {
const roomStats = liveRoomManager.getStats()
const eventStats = roomEvents.getStats()
const roomStats = liveServer!.roomManager.getStats()
const eventStats = liveServer!.roomEvents.getStats()

return {
success: true,
Expand Down
2 changes: 0 additions & 2 deletions core/__tests__/integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,7 @@ describe('Core Framework Integration', () => {

expect(serverExports.FluxStackFramework).toBeDefined()
expect(serverExports.PluginRegistry).toBeDefined()
expect(serverExports.loggerPlugin).toBeDefined()
expect(serverExports.vitePlugin).toBeDefined()
expect(serverExports.staticPlugin).toBeDefined()
expect(serverExports.swaggerPlugin).toBeDefined()
} catch (error) {
// Skip this test if there are environment issues (e.g., esbuild + Windows + Bun)
Expand Down
4 changes: 2 additions & 2 deletions core/framework/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { fluxStackConfig } from "@config"
import { getEnvironmentInfo } from "@core/config"
import { logger, type Logger } from "@core/utils/logger"
import { displayStartupBanner, type StartupInfo } from "@core/utils/logger/startup-banner"
import { componentRegistry } from "@core/server/live"
import { liveServer } from "@core/server/live"
import { FluxStackError } from "@core/utils/errors"
import { createTimer, formatBytes, isProduction, isDevelopment } from "@core/utils/helpers"
import { createHash } from "crypto"
Expand Down Expand Up @@ -826,7 +826,7 @@ export class FluxStackFramework {
vitePort: this.cfg.client?.port,
viteEmbedded: vitePluginActive, // Vite is embedded when plugin is active
swaggerPath: '/swagger', // TODO: Get from swagger plugin config
liveComponents: componentRegistry.getRegisteredComponentNames()
liveComponents: liveServer?.registry.getRegisteredComponentNames() ?? []
}

// Display banner if enabled
Expand Down
2 changes: 1 addition & 1 deletion core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export * from './cli/generators'

// Plugin system (avoid wildcard to prevent conflicts)
export { PluginRegistry } from './plugins/registry'
export { PluginDiscovery, pluginDiscovery } from './plugins/discovery'
export { PluginDiscovery } from './plugins/discovery'
export { PluginManager } from './plugins/manager'
export { PluginUtils } from './plugins'

Expand Down
2 changes: 1 addition & 1 deletion core/plugins/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export { PluginRegistry } from './registry'
export type { PluginRegistryConfig } from './registry'

// Plugin discovery
export { PluginDiscovery, pluginDiscovery } from './discovery'
export { PluginDiscovery } from './discovery'
export type { PluginDiscoveryConfig } from './discovery'

// Plugin configuration management
Expand Down
4 changes: 2 additions & 2 deletions core/server/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// FluxStack framework exports
export { FluxStackFramework } from "../framework/server"
export { vitePlugin, staticPlugin } from "../plugins/built-in"
export { vitePlugin } from "../plugins/built-in"
export { swaggerPlugin } from "../plugins/built-in/swagger"
export { PluginRegistry } from "../plugins/registry"
export * from "../types"

// Live Components exports
export { liveComponentsPlugin, componentRegistry } from "./live"
export { liveComponentsPlugin, liveServer, registerAuthProvider } from "./live"
export { LiveComponent } from "../types/types"

// Static Files Plugin
Expand Down
78 changes: 7 additions & 71 deletions core/server/live/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,78 +33,14 @@ export type {
LiveAuthResult,
} from '@fluxstack/live'

// Backward-compatible singleton accessors
// These lazily access the LiveServer instance created by the plugin
import { liveServer, pendingAuthProviders } from './websocket-plugin'
// Register auth provider — buffers if LiveServer not yet initialized
import { liveServer as _ls, pendingAuthProviders } from './websocket-plugin'
import type { LiveAuthProvider as _LiveAuthProvider } from '@fluxstack/live'
import type { ComponentRegistry as _ComponentRegistry } from '@fluxstack/live'
import type { WebSocketConnectionManager as _WebSocketConnectionManager } from '@fluxstack/live'
import type { RoomStateManager as _RoomStateManager } from '@fluxstack/live'
import type { LiveRoomManager as _LiveRoomManager } from '@fluxstack/live'
import type { RoomEventBus as _RoomEventBus } from '@fluxstack/live'
import type { FileUploadManager as _FileUploadManager } from '@fluxstack/live'
import type { PerformanceMonitor as _PerformanceMonitor } from '@fluxstack/live'
import type { StateSignatureManager as _StateSignatureManager } from '@fluxstack/live'
import type { LiveAuthManager as _LiveAuthManager } from '@fluxstack/live'

function requireLiveServer() {
if (!liveServer) {
throw new Error(
'LiveComponents plugin not initialized. ' +
'Ensure the live-components plugin is loaded before accessing Live singletons.'
)
export function registerAuthProvider(provider: _LiveAuthProvider) {
if (_ls) {
_ls.useAuth(provider)
} else {
pendingAuthProviders.push(provider)
}
return liveServer
}

/**
* Backward-compatible liveAuthManager.
* Buffers register() calls that happen before the plugin setup(),
* then delegates to liveServer.authManager once available.
* @deprecated Access via liveServer.authManager instead
*/
export const liveAuthManager: Pick<_LiveAuthManager, 'authenticate' | 'hasProviders' | 'authorizeRoom' | 'authorizeAction' | 'authorizeComponent'> & { register: (provider: _LiveAuthProvider) => void } = {
register(provider: _LiveAuthProvider) {
if (liveServer) {
liveServer.useAuth(provider)
} else {
pendingAuthProviders.push(provider)
}
},
get authenticate() { return requireLiveServer().authManager.authenticate.bind(requireLiveServer().authManager) },
get hasProviders() { return requireLiveServer().authManager.hasProviders.bind(requireLiveServer().authManager) },
get authorizeRoom() { return requireLiveServer().authManager.authorizeRoom.bind(requireLiveServer().authManager) },
get authorizeAction() { return requireLiveServer().authManager.authorizeAction.bind(requireLiveServer().authManager) },
get authorizeComponent() { return requireLiveServer().authManager.authorizeComponent.bind(requireLiveServer().authManager) },
}

/** Helper to create a typed lazy proxy that delegates to a LiveServer property */
function createLazyProxy<T extends object>(accessor: () => T): T {
return new Proxy({} as T, {
get(_, prop) { return (accessor() as Record<string | symbol, unknown>)[prop] }
})
}

/** @deprecated Access via liveServer.registry instead */
export const componentRegistry = createLazyProxy<_ComponentRegistry>(() => requireLiveServer().registry)

/** @deprecated Access via liveServer.connectionManager instead */
export const connectionManager = createLazyProxy<_WebSocketConnectionManager>(() => requireLiveServer().connectionManager)

/** @deprecated Access via liveServer.roomManager instead */
export const liveRoomManager = createLazyProxy<_LiveRoomManager>(() => requireLiveServer().roomManager)

/** @deprecated Access via liveServer.roomEvents instead */
export const roomEvents = createLazyProxy<_RoomEventBus>(() => requireLiveServer().roomEvents)

/** @deprecated Access via liveServer.fileUploadManager instead */
export const fileUploadManager = createLazyProxy<_FileUploadManager>(() => requireLiveServer().fileUploadManager)

/** @deprecated Access via liveServer.performanceMonitor instead */
export const performanceMonitor = createLazyProxy<_PerformanceMonitor>(() => requireLiveServer().performanceMonitor)

/** @deprecated Access via liveServer.stateSignature instead */
export const stateSignature = createLazyProxy<_StateSignatureManager>(() => requireLiveServer().stateSignature)

// Room state backward compat
export const roomState = createLazyProxy<_LiveRoomManager>(() => requireLiveServer().roomManager)
2 changes: 1 addition & 1 deletion create-fluxstack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ FluxStack includes several built-in plugins that are ready to use:

\`\`\`typescript
// app/server/index.ts
import { loggerPlugin, swaggerPlugin, staticPlugin } from "@core/server"
import { swaggerPlugin } from "@core/server"

// Add built-in plugins
app.use(loggerPlugin)
Expand Down
4 changes: 2 additions & 2 deletions plugins/crypto-auth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ type Plugin = FluxStack.Plugin
import { Elysia, t } from "elysia"
import { CryptoAuthService, AuthMiddleware } from "./server"
import { CryptoAuthLiveProvider } from "./server/CryptoAuthLiveProvider"
import { liveAuthManager } from "@core/server/live"
import { registerAuthProvider } from "@core/server/live"
import { makeProtectedRouteCommand } from "./cli/make-protected-route.command"

// ✅ Plugin carrega sua própria configuração (da pasta config/ do plugin)
Expand Down Expand Up @@ -91,7 +91,7 @@ export const cryptoAuthPlugin: Plugin = {
;(global as any).cryptoAuthMiddleware = authMiddleware

// 🔒 Register as LiveAuthProvider for Live Components WebSocket auth
liveAuthManager.register(new CryptoAuthLiveProvider(authService))
registerAuthProvider(new CryptoAuthLiveProvider(authService))
context.logger.info('🔒 Crypto Auth registered as Live Components auth provider')

// Store plugin info for table display
Expand Down
Loading
Loading