create-fluxstack 1.0.13 → 1.0.15

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.
Files changed (214) hide show
  1. package/.env.example +29 -29
  2. package/app/client/README.md +69 -69
  3. package/app/client/index.html +14 -13
  4. package/app/client/src/App.tsx +157 -524
  5. package/app/client/src/components/ErrorBoundary.tsx +107 -0
  6. package/app/client/src/components/ErrorDisplay.css +365 -0
  7. package/app/client/src/components/ErrorDisplay.tsx +258 -0
  8. package/app/client/src/components/FluxStackConfig.tsx +1321 -0
  9. package/app/client/src/components/HybridLiveCounter.tsx +140 -0
  10. package/app/client/src/components/LiveClock.tsx +286 -0
  11. package/app/client/src/components/MainLayout.tsx +390 -0
  12. package/app/client/src/components/SidebarNavigation.tsx +391 -0
  13. package/app/client/src/components/StateDemo.tsx +178 -0
  14. package/app/client/src/components/SystemMonitor.tsx +1038 -0
  15. package/app/client/src/components/Teste.tsx +104 -0
  16. package/app/client/src/components/UserProfile.tsx +809 -0
  17. package/app/client/src/hooks/useAuth.ts +39 -0
  18. package/app/client/src/hooks/useNotifications.ts +56 -0
  19. package/app/client/src/lib/eden-api.ts +189 -53
  20. package/app/client/src/lib/errors.ts +340 -0
  21. package/app/client/src/lib/hooks/useErrorHandler.ts +258 -0
  22. package/app/client/src/lib/index.ts +45 -0
  23. package/app/client/src/main.tsx +3 -2
  24. package/app/client/src/pages/ApiDocs.tsx +182 -0
  25. package/app/client/src/pages/Demo.tsx +174 -0
  26. package/app/client/src/pages/HybridLive.tsx +263 -0
  27. package/app/client/src/pages/Overview.tsx +155 -0
  28. package/app/client/src/store/README.md +43 -0
  29. package/app/client/src/store/index.ts +16 -0
  30. package/app/client/src/store/slices/uiSlice.ts +151 -0
  31. package/app/client/src/store/slices/userSlice.ts +161 -0
  32. package/app/client/src/test/README.md +257 -0
  33. package/app/client/src/test/setup.ts +70 -0
  34. package/app/client/src/test/types.ts +12 -0
  35. package/app/client/src/vite-env.d.ts +1 -1
  36. package/app/client/tsconfig.app.json +44 -43
  37. package/app/client/tsconfig.json +7 -7
  38. package/app/client/tsconfig.node.json +25 -25
  39. package/app/client/zustand-setup.md +65 -0
  40. package/app/server/controllers/users.controller.ts +68 -68
  41. package/app/server/index.ts +9 -1
  42. package/app/server/live/CounterComponent.ts +191 -0
  43. package/app/server/live/FluxStackConfig.ts +529 -0
  44. package/app/server/live/LiveClockComponent.ts +214 -0
  45. package/app/server/live/SidebarNavigation.ts +156 -0
  46. package/app/server/live/SystemMonitor.ts +594 -0
  47. package/app/server/live/SystemMonitorIntegration.ts +151 -0
  48. package/app/server/live/TesteComponent.ts +87 -0
  49. package/app/server/live/UserProfileComponent.ts +135 -0
  50. package/app/server/live/register-components.ts +28 -0
  51. package/app/server/middleware/auth.ts +136 -0
  52. package/app/server/middleware/errorHandling.ts +250 -0
  53. package/app/server/middleware/index.ts +10 -0
  54. package/app/server/middleware/rateLimit.ts +193 -0
  55. package/app/server/middleware/requestLogging.ts +215 -0
  56. package/app/server/middleware/validation.ts +270 -0
  57. package/app/server/routes/index.ts +14 -2
  58. package/app/server/routes/upload.ts +92 -0
  59. package/app/server/routes/users.routes.ts +2 -9
  60. package/app/server/services/NotificationService.ts +302 -0
  61. package/app/server/services/UserService.ts +222 -0
  62. package/app/server/services/index.ts +46 -0
  63. package/core/cli/commands/plugin-deps.ts +263 -0
  64. package/core/cli/generators/README.md +339 -0
  65. package/core/cli/generators/component.ts +770 -0
  66. package/core/cli/generators/controller.ts +299 -0
  67. package/core/cli/generators/index.ts +144 -0
  68. package/core/cli/generators/interactive.ts +228 -0
  69. package/core/cli/generators/prompts.ts +83 -0
  70. package/core/cli/generators/route.ts +513 -0
  71. package/core/cli/generators/service.ts +465 -0
  72. package/core/cli/generators/template-engine.ts +154 -0
  73. package/core/cli/generators/types.ts +71 -0
  74. package/core/cli/generators/utils.ts +192 -0
  75. package/core/cli/index.ts +69 -0
  76. package/core/cli/plugin-discovery.ts +16 -85
  77. package/core/client/fluxstack.ts +17 -0
  78. package/core/client/hooks/index.ts +7 -0
  79. package/core/client/hooks/state-validator.ts +130 -0
  80. package/core/client/hooks/useAuth.ts +49 -0
  81. package/core/client/hooks/useChunkedUpload.ts +258 -0
  82. package/core/client/hooks/useHybridLiveComponent.ts +967 -0
  83. package/core/client/hooks/useWebSocket.ts +373 -0
  84. package/core/client/index.ts +47 -0
  85. package/core/client/state/createStore.ts +193 -0
  86. package/core/client/state/index.ts +15 -0
  87. package/core/config/env-dynamic.ts +1 -1
  88. package/core/config/env.ts +2 -1
  89. package/core/config/runtime-config.ts +3 -3
  90. package/core/config/schema.ts +84 -49
  91. package/core/framework/server.ts +30 -0
  92. package/core/index.ts +25 -0
  93. package/core/live/ComponentRegistry.ts +399 -0
  94. package/core/live/types.ts +164 -0
  95. package/core/plugins/built-in/live-components/commands/create-live-component.ts +1201 -0
  96. package/core/plugins/built-in/live-components/index.ts +27 -0
  97. package/core/plugins/built-in/logger/index.ts +1 -1
  98. package/core/plugins/built-in/monitoring/index.ts +1 -1
  99. package/core/plugins/built-in/static/index.ts +1 -1
  100. package/core/plugins/built-in/swagger/index.ts +1 -1
  101. package/core/plugins/built-in/vite/index.ts +1 -1
  102. package/core/plugins/dependency-manager.ts +384 -0
  103. package/core/plugins/index.ts +5 -1
  104. package/core/plugins/manager.ts +7 -3
  105. package/core/plugins/registry.ts +88 -10
  106. package/core/plugins/types.ts +11 -11
  107. package/core/server/framework.ts +43 -0
  108. package/core/server/index.ts +11 -1
  109. package/core/server/live/ComponentRegistry.ts +1017 -0
  110. package/core/server/live/FileUploadManager.ts +272 -0
  111. package/core/server/live/LiveComponentPerformanceMonitor.ts +930 -0
  112. package/core/server/live/SingleConnectionManager.ts +0 -0
  113. package/core/server/live/StateSignature.ts +644 -0
  114. package/core/server/live/WebSocketConnectionManager.ts +688 -0
  115. package/core/server/live/websocket-plugin.ts +435 -0
  116. package/core/server/middleware/errorHandling.ts +141 -0
  117. package/core/server/middleware/index.ts +16 -0
  118. package/core/server/plugins/static-files-plugin.ts +232 -0
  119. package/core/server/services/BaseService.ts +95 -0
  120. package/core/server/services/ServiceContainer.ts +144 -0
  121. package/core/server/services/index.ts +9 -0
  122. package/core/templates/create-project.ts +196 -33
  123. package/core/testing/index.ts +10 -0
  124. package/core/testing/setup.ts +74 -0
  125. package/core/types/build.ts +38 -14
  126. package/core/types/types.ts +319 -0
  127. package/core/utils/env-runtime.ts +7 -0
  128. package/core/utils/errors/handlers.ts +264 -39
  129. package/core/utils/errors/index.ts +528 -18
  130. package/core/utils/errors/middleware.ts +114 -0
  131. package/core/utils/logger/formatters.ts +222 -0
  132. package/core/utils/logger/index.ts +167 -48
  133. package/core/utils/logger/middleware.ts +253 -0
  134. package/core/utils/logger/performance.ts +384 -0
  135. package/core/utils/logger/transports.ts +365 -0
  136. package/create-fluxstack.ts +296 -296
  137. package/fluxstack.config.ts +17 -1
  138. package/package-template.json +66 -66
  139. package/package.json +31 -6
  140. package/public/README.md +16 -0
  141. package/vite.config.ts +29 -14
  142. package/.claude/settings.local.json +0 -74
  143. package/.github/workflows/ci-build-tests.yml +0 -480
  144. package/.github/workflows/dependency-management.yml +0 -324
  145. package/.github/workflows/release-validation.yml +0 -355
  146. package/.kiro/specs/fluxstack-architecture-optimization/design.md +0 -700
  147. package/.kiro/specs/fluxstack-architecture-optimization/requirements.md +0 -127
  148. package/.kiro/specs/fluxstack-architecture-optimization/tasks.md +0 -330
  149. package/CLAUDE.md +0 -200
  150. package/Dockerfile +0 -58
  151. package/Dockerfile.backend +0 -52
  152. package/Dockerfile.frontend +0 -54
  153. package/README-Docker.md +0 -85
  154. package/ai-context/00-QUICK-START.md +0 -86
  155. package/ai-context/README.md +0 -88
  156. package/ai-context/development/eden-treaty-guide.md +0 -362
  157. package/ai-context/development/patterns.md +0 -382
  158. package/ai-context/development/plugins-guide.md +0 -572
  159. package/ai-context/examples/crud-complete.md +0 -626
  160. package/ai-context/project/architecture.md +0 -399
  161. package/ai-context/project/overview.md +0 -213
  162. package/ai-context/recent-changes/eden-treaty-refactor.md +0 -281
  163. package/ai-context/recent-changes/type-inference-fix.md +0 -223
  164. package/ai-context/reference/environment-vars.md +0 -384
  165. package/ai-context/reference/troubleshooting.md +0 -407
  166. package/app/client/src/components/TestPage.tsx +0 -453
  167. package/bun.lock +0 -1063
  168. package/bunfig.toml +0 -16
  169. package/core/__tests__/integration.test.ts +0 -227
  170. package/core/build/index.ts +0 -186
  171. package/core/config/__tests__/config-loader.test.ts +0 -554
  172. package/core/config/__tests__/config-merger.test.ts +0 -657
  173. package/core/config/__tests__/env-converter.test.ts +0 -372
  174. package/core/config/__tests__/env-processor.test.ts +0 -431
  175. package/core/config/__tests__/env.test.ts +0 -452
  176. package/core/config/__tests__/integration.test.ts +0 -418
  177. package/core/config/__tests__/loader.test.ts +0 -331
  178. package/core/config/__tests__/schema.test.ts +0 -129
  179. package/core/config/__tests__/validator.test.ts +0 -318
  180. package/core/framework/__tests__/server.test.ts +0 -233
  181. package/core/plugins/__tests__/built-in.test.ts.disabled +0 -366
  182. package/core/plugins/__tests__/manager.test.ts +0 -398
  183. package/core/plugins/__tests__/monitoring.test.ts +0 -401
  184. package/core/plugins/__tests__/registry.test.ts +0 -335
  185. package/core/utils/__tests__/errors.test.ts +0 -139
  186. package/core/utils/__tests__/helpers.test.ts +0 -297
  187. package/core/utils/__tests__/logger.test.ts +0 -141
  188. package/create-test-app.ts +0 -156
  189. package/docker-compose.microservices.yml +0 -75
  190. package/docker-compose.simple.yml +0 -57
  191. package/docker-compose.yml +0 -71
  192. package/eslint.config.js +0 -23
  193. package/flux-cli.ts +0 -214
  194. package/nginx-lb.conf +0 -37
  195. package/publish.sh +0 -63
  196. package/run-clean.ts +0 -26
  197. package/run-env-tests.ts +0 -313
  198. package/tailwind.config.js +0 -34
  199. package/tests/__mocks__/api.ts +0 -56
  200. package/tests/fixtures/users.ts +0 -69
  201. package/tests/integration/api/users.routes.test.ts +0 -221
  202. package/tests/setup.ts +0 -29
  203. package/tests/unit/app/client/App-simple.test.tsx +0 -56
  204. package/tests/unit/app/client/App.test.tsx.skip +0 -237
  205. package/tests/unit/app/client/eden-api.test.ts +0 -186
  206. package/tests/unit/app/client/simple.test.tsx +0 -23
  207. package/tests/unit/app/controllers/users.controller.test.ts +0 -150
  208. package/tests/unit/core/create-project.test.ts.skip +0 -95
  209. package/tests/unit/core/framework.test.ts +0 -144
  210. package/tests/unit/core/plugins/logger.test.ts.skip +0 -268
  211. package/tests/unit/core/plugins/vite.test.ts.disabled +0 -188
  212. package/tests/utils/test-helpers.ts +0 -61
  213. package/vitest.config.ts +0 -50
  214. package/workspace.json +0 -6
@@ -0,0 +1,65 @@
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,69 +1,69 @@
1
- import type { User, CreateUserRequest, UserResponse } from '../types'
2
-
3
- let users: User[] = [
4
- { id: 1, name: "João", email: "joao@example.com", createdAt: new Date() },
5
- { id: 2, name: "Maria", email: "maria@example.com", createdAt: new Date() }
6
- ]
7
-
8
- export class UsersController {
9
- static async getUsers() {
10
- return { users }
11
- }
12
-
13
- static resetForTesting() {
14
- users.splice(0, users.length)
15
- users.push(
16
- { id: 1, name: "João", email: "joao@example.com", createdAt: new Date() },
17
- { id: 2, name: "Maria", email: "maria@example.com", createdAt: new Date() }
18
- )
19
- }
20
-
21
- static async createUser(userData: CreateUserRequest): Promise<UserResponse> {
22
- const existingUser = users.find(u => u.email === userData.email)
23
-
24
- if (existingUser) {
25
- return {
26
- success: false,
27
- message: "Email já está em uso"
28
- }
29
- }
30
-
31
- const newUser: User = {
32
- id: Date.now(),
33
- name: userData.name,
34
- email: userData.email,
35
- createdAt: new Date()
36
- }
37
-
38
- users.push(newUser)
39
-
40
- return {
41
- success: true,
42
- user: newUser
43
- }
44
- }
45
-
46
- static async getUserById(id: number) {
47
- const user = users.find(u => u.id === id)
48
- return user ? { user } : null
49
- }
50
-
51
- static async deleteUser(id: number): Promise<UserResponse> {
52
- const userIndex = users.findIndex(u => u.id === id)
53
-
54
- if (userIndex === -1) {
55
- return {
56
- success: false,
57
- message: "Usuário não encontrado"
58
- }
59
- }
60
-
61
- const deletedUser = users.splice(userIndex, 1)[0]
62
-
63
- return {
64
- success: true,
65
- user: deletedUser,
66
- message: "Usuário deletado com sucesso"
67
- }
68
- }
1
+ import type { User, CreateUserRequest, UserResponse } from '../types'
2
+
3
+ let users: User[] = [
4
+ { id: 1, name: "João", email: "joao@example.com", createdAt: new Date() },
5
+ { id: 2, name: "Maria", email: "maria@example.com", createdAt: new Date() }
6
+ ]
7
+
8
+ export class UsersController {
9
+ static async getUsers() {
10
+ return { users }
11
+ }
12
+
13
+ static resetForTesting() {
14
+ users.splice(0, users.length)
15
+ users.push(
16
+ { id: 1, name: "João", email: "joao@example.com", createdAt: new Date() },
17
+ { id: 2, name: "Maria", email: "maria@example.com", createdAt: new Date() }
18
+ )
19
+ }
20
+
21
+ static async createUser(userData: CreateUserRequest): Promise<UserResponse> {
22
+ const existingUser = users.find(u => u.email === userData.email)
23
+
24
+ if (existingUser) {
25
+ return {
26
+ success: false,
27
+ message: "Email já está em uso"
28
+ }
29
+ }
30
+
31
+ const newUser: User = {
32
+ id: Date.now(),
33
+ name: userData.name,
34
+ email: userData.email,
35
+ createdAt: new Date()
36
+ }
37
+
38
+ users.push(newUser)
39
+
40
+ return {
41
+ success: true,
42
+ user: newUser
43
+ }
44
+ }
45
+
46
+ static async getUserById(id: number) {
47
+ const user = users.find(u => u.id === id)
48
+ return user ? { user } : null
49
+ }
50
+
51
+ static async deleteUser(id: number): Promise<UserResponse> {
52
+ const userIndex = users.findIndex(u => u.id === id)
53
+
54
+ if (userIndex === -1) {
55
+ return {
56
+ success: false,
57
+ message: "Usuário não encontrado"
58
+ }
59
+ }
60
+
61
+ const deletedUser = users.splice(userIndex, 1)[0]
62
+
63
+ return {
64
+ success: true,
65
+ user: deletedUser,
66
+ message: "Usuário deletado com sucesso"
67
+ }
68
+ }
69
69
  }
@@ -1,9 +1,11 @@
1
1
  // User application entry point
2
- import { FluxStackFramework, loggerPlugin, vitePlugin, swaggerPlugin, staticPlugin } from "@/core/server"
2
+ import { FluxStackFramework, loggerPlugin, vitePlugin, swaggerPlugin, staticPlugin, liveComponentsPlugin, staticFilesPlugin } from "@/core/server"
3
3
  import { isDevelopment } from "@/core/utils/helpers"
4
4
  import { apiRoutes } from "./routes"
5
5
  // Import sistema de env dinâmico simplificado
6
6
  import { env, helpers } from "@/core/utils/env-runtime-v2"
7
+ // Import live components registration
8
+ import "./live/register-components"
7
9
 
8
10
  console.log('🔧 Loading dynamic environment configuration...')
9
11
  console.log(`📊 Environment: ${env.NODE_ENV}`) // Direto!
@@ -52,6 +54,10 @@ if (isDevelopment()) {
52
54
  } else {
53
55
  app.use(staticPlugin)
54
56
  }
57
+
58
+ // Add static files AFTER Vite to avoid conflicts, but BEFORE Live Components
59
+ app.use(staticFilesPlugin) // Add Static Files support
60
+ app.use(liveComponentsPlugin) // Add Live Components support
55
61
 
56
62
 
57
63
  // Adicionar rota de teste para mostrar env dinâmico (antes das rotas)
@@ -100,5 +106,7 @@ app.listen(() => {
100
106
  console.log('💡 Mude as env vars e reinicie para ver a diferença!')
101
107
  })
102
108
 
109
+
110
+
103
111
  // Exportar tipo da aplicação para Eden Treaty (método correto)
104
112
  export type App = typeof app
@@ -0,0 +1,191 @@
1
+ // 🔥 Example Live Component - Counter
2
+
3
+ import { LiveComponent } from "../../../core/types/types"
4
+
5
+ interface CounterState {
6
+ count: number
7
+ title: string
8
+ step: number
9
+ history: number[]
10
+ lastUpdated: Date
11
+ }
12
+
13
+ export class CounterComponent extends LiveComponent<CounterState> {
14
+
15
+ constructor(initialState: CounterState, ws: any, options?: { room?: string; userId?: string }) {
16
+ super(initialState, ws, options)
17
+
18
+ // Ensure history is initialized
19
+ if (!this.state.history) {
20
+ this.state.history = []
21
+ }
22
+
23
+ // Log component creation
24
+ console.log(`🔢 Counter component created: ${this.id}`, {
25
+ initialState,
26
+ room: options?.room,
27
+ userId: options?.userId
28
+ })
29
+ }
30
+
31
+ // Action: Increment counter
32
+ async increment(amount: number = 1) {
33
+ const newCount = this.state.count + amount
34
+ const newHistory = [...this.state.history, newCount]
35
+
36
+ this.setState({
37
+ count: newCount,
38
+ history: newHistory.slice(-10), // Keep last 10 values
39
+ lastUpdated: new Date()
40
+ })
41
+
42
+ // Broadcast to room if in multi-user mode
43
+ if (this.room) {
44
+ this.broadcast('COUNTER_INCREMENTED', {
45
+ count: newCount,
46
+ amount,
47
+ userId: this.userId
48
+ })
49
+ }
50
+
51
+ console.log(`🔢 Counter incremented to ${newCount} (step: ${amount})`)
52
+ return { success: true, count: newCount }
53
+ }
54
+
55
+ // Action: Decrement counter
56
+ async decrement(amount: number = 1) {
57
+ const newCount = Math.max(0, this.state.count - amount)
58
+ const newHistory = [...this.state.history, newCount]
59
+
60
+ this.setState({
61
+ count: newCount,
62
+ history: newHistory.slice(-10),
63
+ lastUpdated: new Date()
64
+ })
65
+
66
+ if (this.room) {
67
+ this.broadcast('COUNTER_DECREMENTED', {
68
+ count: newCount,
69
+ amount,
70
+ userId: this.userId
71
+ })
72
+ }
73
+
74
+ console.log(`🔢 Counter decremented to ${newCount} (step: ${amount})`)
75
+ return { success: true, count: newCount }
76
+ }
77
+
78
+ // Action: Reset counter
79
+ async reset() {
80
+ this.setState({
81
+ count: 0,
82
+ history: [0],
83
+ lastUpdated: new Date()
84
+ })
85
+
86
+ if (this.room) {
87
+ this.broadcast('COUNTER_RESET', {
88
+ userId: this.userId
89
+ })
90
+ }
91
+
92
+ console.log(`🔢 Counter reset`)
93
+ return { success: true, count: 0 }
94
+ }
95
+
96
+ // Action: Set step size
97
+ async setStep(step: number) {
98
+ this.setState({
99
+ step: Math.max(1, step),
100
+ lastUpdated: new Date()
101
+ })
102
+
103
+ console.log(`🔢 Counter step set to ${step}`)
104
+ return { success: true, step }
105
+ }
106
+
107
+ // Action: Update title
108
+ async updateTitle(data: { title: string }) {
109
+ const newTitle = data.title.trim()
110
+
111
+ // Validate title
112
+ if (!newTitle || newTitle.length > 50) {
113
+ throw new Error('Title must be 1-50 characters')
114
+ }
115
+
116
+ this.setState({
117
+ title: newTitle,
118
+ lastUpdated: new Date()
119
+ })
120
+
121
+ console.log(`📝 Title updated to: "${newTitle}"`)
122
+ return { success: true, title: newTitle }
123
+ }
124
+
125
+ // Action: Set title
126
+ async setTitle(title: string) {
127
+ this.setState({
128
+ title: title.substring(0, 50), // Max 50 chars
129
+ lastUpdated: new Date()
130
+ })
131
+
132
+ console.log(`🔢 Counter title set to "${title}"`)
133
+ return { success: true, title }
134
+ }
135
+
136
+ // Action: Bulk update
137
+ async bulkUpdate(updates: { count?: number; title?: string; step?: number }) {
138
+ const newState: Partial<CounterState> = {
139
+ lastUpdated: new Date()
140
+ }
141
+
142
+ if (updates.count !== undefined) {
143
+ newState.count = Math.max(0, updates.count)
144
+ newState.history = [...this.state.history, updates.count].slice(-10)
145
+ }
146
+
147
+ if (updates.title !== undefined) {
148
+ newState.title = updates.title.substring(0, 50)
149
+ }
150
+
151
+ if (updates.step !== undefined) {
152
+ newState.step = Math.max(1, updates.step)
153
+ }
154
+
155
+ this.setState(newState)
156
+
157
+ if (this.room) {
158
+ this.broadcast('COUNTER_BULK_UPDATE', {
159
+ updates: newState,
160
+ userId: this.userId
161
+ })
162
+ }
163
+
164
+ console.log(`🔢 Counter bulk updated`, updates)
165
+ return { success: true, updates: newState }
166
+ }
167
+
168
+ // Get computed properties
169
+ async getStats() {
170
+ const { count, history, step } = this.state
171
+
172
+ const stats = {
173
+ current: count,
174
+ min: Math.min(...history),
175
+ max: Math.max(...history),
176
+ average: history.reduce((a, b) => a + b, 0) / history.length,
177
+ step,
178
+ historyLength: history.length,
179
+ canIncrement: true,
180
+ canDecrement: count > 0
181
+ }
182
+
183
+ return { success: true, stats }
184
+ }
185
+
186
+ // Override destroy for cleanup
187
+ public destroy() {
188
+ console.log(`🗑️ Counter component ${this.id} destroyed`)
189
+ super.destroy()
190
+ }
191
+ }