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.
Files changed (257) hide show
  1. package/.dockerignore +1 -2
  2. package/Dockerfile +8 -8
  3. package/LLMD/INDEX.md +64 -0
  4. package/LLMD/MAINTENANCE.md +197 -0
  5. package/LLMD/MIGRATION.md +156 -0
  6. package/LLMD/config/.gitkeep +1 -0
  7. package/LLMD/config/declarative-system.md +268 -0
  8. package/LLMD/config/environment-vars.md +327 -0
  9. package/LLMD/config/runtime-reload.md +401 -0
  10. package/LLMD/core/.gitkeep +1 -0
  11. package/LLMD/core/build-system.md +599 -0
  12. package/LLMD/core/framework-lifecycle.md +229 -0
  13. package/LLMD/core/plugin-system.md +451 -0
  14. package/LLMD/patterns/.gitkeep +1 -0
  15. package/LLMD/patterns/anti-patterns.md +297 -0
  16. package/LLMD/patterns/project-structure.md +264 -0
  17. package/LLMD/patterns/type-safety.md +440 -0
  18. package/LLMD/reference/.gitkeep +1 -0
  19. package/LLMD/reference/cli-commands.md +250 -0
  20. package/LLMD/reference/plugin-hooks.md +357 -0
  21. package/LLMD/reference/routing.md +39 -0
  22. package/LLMD/reference/troubleshooting.md +364 -0
  23. package/LLMD/resources/.gitkeep +1 -0
  24. package/LLMD/resources/controllers.md +465 -0
  25. package/LLMD/resources/live-components.md +703 -0
  26. package/LLMD/resources/live-rooms.md +482 -0
  27. package/LLMD/resources/live-upload.md +130 -0
  28. package/LLMD/resources/plugins-external.md +617 -0
  29. package/LLMD/resources/routes-eden.md +254 -0
  30. package/README.md +37 -17
  31. package/app/client/index.html +0 -1
  32. package/app/client/src/App.tsx +107 -150
  33. package/app/client/src/components/AppLayout.tsx +68 -0
  34. package/app/client/src/components/BackButton.tsx +13 -0
  35. package/app/client/src/components/DemoPage.tsx +20 -0
  36. package/app/client/src/components/LiveUploadWidget.tsx +204 -0
  37. package/app/client/src/lib/eden-api.ts +85 -60
  38. package/app/client/src/live/ChatDemo.tsx +107 -0
  39. package/app/client/src/live/CounterDemo.tsx +206 -0
  40. package/app/client/src/live/FormDemo.tsx +119 -0
  41. package/app/client/src/live/RoomChatDemo.tsx +242 -0
  42. package/app/client/src/live/UploadDemo.tsx +21 -0
  43. package/app/client/src/main.tsx +4 -1
  44. package/app/client/src/pages/ApiTestPage.tsx +108 -0
  45. package/app/client/src/pages/HomePage.tsx +76 -0
  46. package/app/server/app.ts +1 -4
  47. package/app/server/controllers/users.controller.ts +36 -44
  48. package/app/server/index.ts +25 -35
  49. package/app/server/live/LiveChat.ts +77 -0
  50. package/app/server/live/LiveCounter.ts +67 -0
  51. package/app/server/live/LiveForm.ts +63 -0
  52. package/app/server/live/LiveLocalCounter.ts +32 -0
  53. package/app/server/live/LiveRoomChat.ts +285 -0
  54. package/app/server/live/LiveUpload.ts +81 -0
  55. package/app/server/routes/index.ts +3 -1
  56. package/app/server/routes/room.routes.ts +117 -0
  57. package/app/server/routes/users.routes.ts +35 -27
  58. package/app/shared/types/index.ts +14 -2
  59. package/config/app.config.ts +2 -62
  60. package/config/client.config.ts +2 -95
  61. package/config/database.config.ts +2 -99
  62. package/config/fluxstack.config.ts +25 -45
  63. package/config/index.ts +57 -38
  64. package/config/monitoring.config.ts +2 -114
  65. package/config/plugins.config.ts +2 -80
  66. package/config/server.config.ts +2 -68
  67. package/config/services.config.ts +2 -130
  68. package/config/system/app.config.ts +29 -0
  69. package/config/system/build.config.ts +49 -0
  70. package/config/system/client.config.ts +68 -0
  71. package/config/system/database.config.ts +17 -0
  72. package/config/system/fluxstack.config.ts +114 -0
  73. package/config/{logger.config.ts → system/logger.config.ts} +3 -1
  74. package/config/system/monitoring.config.ts +114 -0
  75. package/config/system/plugins.config.ts +84 -0
  76. package/config/{runtime.config.ts → system/runtime.config.ts} +1 -1
  77. package/config/system/server.config.ts +68 -0
  78. package/config/system/services.config.ts +46 -0
  79. package/config/{system.config.ts → system/system.config.ts} +1 -1
  80. package/core/build/flux-plugins-generator.ts +325 -325
  81. package/core/build/index.ts +39 -27
  82. package/core/build/live-components-generator.ts +3 -3
  83. package/core/build/optimizer.ts +235 -235
  84. package/core/cli/command-registry.ts +6 -4
  85. package/core/cli/commands/build.ts +79 -0
  86. package/core/cli/commands/create.ts +54 -0
  87. package/core/cli/commands/dev.ts +101 -0
  88. package/core/cli/commands/help.ts +34 -0
  89. package/core/cli/commands/index.ts +34 -0
  90. package/core/cli/commands/make-plugin.ts +90 -0
  91. package/core/cli/commands/plugin-add.ts +197 -0
  92. package/core/cli/commands/plugin-deps.ts +2 -2
  93. package/core/cli/commands/plugin-list.ts +208 -0
  94. package/core/cli/commands/plugin-remove.ts +170 -0
  95. package/core/cli/generators/component.ts +769 -769
  96. package/core/cli/generators/controller.ts +1 -1
  97. package/core/cli/generators/index.ts +146 -146
  98. package/core/cli/generators/interactive.ts +227 -227
  99. package/core/cli/generators/plugin.ts +2 -2
  100. package/core/cli/generators/prompts.ts +82 -82
  101. package/core/cli/generators/route.ts +6 -6
  102. package/core/cli/generators/service.ts +2 -2
  103. package/core/cli/generators/template-engine.ts +4 -3
  104. package/core/cli/generators/types.ts +2 -2
  105. package/core/cli/generators/utils.ts +191 -191
  106. package/core/cli/index.ts +115 -686
  107. package/core/cli/plugin-discovery.ts +2 -2
  108. package/core/client/LiveComponentsProvider.tsx +60 -8
  109. package/core/client/api/eden.ts +183 -0
  110. package/core/client/api/index.ts +11 -0
  111. package/core/client/components/Live.tsx +104 -0
  112. package/core/client/fluxstack.ts +1 -9
  113. package/core/client/hooks/AdaptiveChunkSizer.ts +215 -215
  114. package/core/client/hooks/state-validator.ts +1 -1
  115. package/core/client/hooks/useAuth.ts +48 -48
  116. package/core/client/hooks/useChunkedUpload.ts +85 -35
  117. package/core/client/hooks/useLiveChunkedUpload.ts +87 -0
  118. package/core/client/hooks/useLiveComponent.ts +800 -0
  119. package/core/client/hooks/useLiveUpload.ts +71 -0
  120. package/core/client/hooks/useRoom.ts +409 -0
  121. package/core/client/hooks/useRoomProxy.ts +382 -0
  122. package/core/client/index.ts +17 -68
  123. package/core/client/standalone-entry.ts +8 -0
  124. package/core/client/standalone.ts +74 -53
  125. package/core/client/state/createStore.ts +192 -192
  126. package/core/client/state/index.ts +14 -14
  127. package/core/config/index.ts +70 -291
  128. package/core/config/schema.ts +42 -723
  129. package/core/framework/client.ts +131 -131
  130. package/core/framework/index.ts +7 -7
  131. package/core/framework/server.ts +47 -40
  132. package/core/framework/types.ts +2 -2
  133. package/core/index.ts +23 -4
  134. package/core/live/ComponentRegistry.ts +3 -3
  135. package/core/live/types.ts +77 -0
  136. package/core/plugins/built-in/index.ts +134 -134
  137. package/core/plugins/built-in/live-components/commands/create-live-component.ts +242 -1066
  138. package/core/plugins/built-in/live-components/index.ts +1 -1
  139. package/core/plugins/built-in/monitoring/index.ts +111 -47
  140. package/core/plugins/built-in/static/index.ts +1 -1
  141. package/core/plugins/built-in/swagger/index.ts +68 -265
  142. package/core/plugins/built-in/vite/index.ts +85 -185
  143. package/core/plugins/built-in/vite/vite-dev.ts +10 -16
  144. package/core/plugins/config.ts +9 -7
  145. package/core/plugins/dependency-manager.ts +31 -1
  146. package/core/plugins/discovery.ts +19 -7
  147. package/core/plugins/executor.ts +2 -2
  148. package/core/plugins/index.ts +203 -203
  149. package/core/plugins/manager.ts +27 -39
  150. package/core/plugins/module-resolver.ts +19 -8
  151. package/core/plugins/registry.ts +255 -19
  152. package/core/plugins/types.ts +20 -53
  153. package/core/server/framework.ts +66 -43
  154. package/core/server/index.ts +15 -15
  155. package/core/server/live/ComponentRegistry.ts +78 -71
  156. package/core/server/live/FileUploadManager.ts +23 -10
  157. package/core/server/live/LiveComponentPerformanceMonitor.ts +1 -1
  158. package/core/server/live/LiveRoomManager.ts +261 -0
  159. package/core/server/live/RoomEventBus.ts +234 -0
  160. package/core/server/live/RoomStateManager.ts +172 -0
  161. package/core/server/live/StateSignature.ts +643 -643
  162. package/core/server/live/WebSocketConnectionManager.ts +30 -19
  163. package/core/server/live/auto-generated-components.ts +21 -9
  164. package/core/server/live/index.ts +14 -0
  165. package/core/server/live/websocket-plugin.ts +214 -67
  166. package/core/server/middleware/elysia-helpers.ts +7 -2
  167. package/core/server/middleware/errorHandling.ts +1 -1
  168. package/core/server/middleware/index.ts +31 -31
  169. package/core/server/plugins/database.ts +180 -180
  170. package/core/server/plugins/static-files-plugin.ts +69 -69
  171. package/core/server/plugins/swagger.ts +1 -1
  172. package/core/server/rooms/RoomBroadcaster.ts +357 -0
  173. package/core/server/rooms/RoomSystem.ts +463 -0
  174. package/core/server/rooms/index.ts +13 -0
  175. package/core/server/services/BaseService.ts +1 -1
  176. package/core/server/services/ServiceContainer.ts +1 -1
  177. package/core/server/services/index.ts +8 -8
  178. package/core/templates/create-project.ts +12 -12
  179. package/core/testing/index.ts +9 -9
  180. package/core/testing/setup.ts +73 -73
  181. package/core/types/api.ts +168 -168
  182. package/core/types/build.ts +219 -219
  183. package/core/types/config.ts +56 -26
  184. package/core/types/index.ts +4 -4
  185. package/core/types/plugin.ts +107 -107
  186. package/core/types/types.ts +353 -14
  187. package/core/utils/build-logger.ts +324 -324
  188. package/core/utils/config-schema.ts +480 -480
  189. package/core/utils/env.ts +2 -8
  190. package/core/utils/errors/codes.ts +114 -114
  191. package/core/utils/errors/handlers.ts +36 -1
  192. package/core/utils/errors/index.ts +49 -5
  193. package/core/utils/errors/middleware.ts +113 -113
  194. package/core/utils/helpers.ts +6 -16
  195. package/core/utils/index.ts +17 -17
  196. package/core/utils/logger/colors.ts +114 -114
  197. package/core/utils/logger/config.ts +13 -9
  198. package/core/utils/logger/formatter.ts +82 -82
  199. package/core/utils/logger/group-logger.ts +101 -101
  200. package/core/utils/logger/index.ts +6 -1
  201. package/core/utils/logger/stack-trace.ts +3 -1
  202. package/core/utils/logger/startup-banner.ts +82 -82
  203. package/core/utils/logger/winston-logger.ts +152 -152
  204. package/core/utils/monitoring/index.ts +211 -211
  205. package/core/utils/sync-version.ts +66 -66
  206. package/core/utils/version.ts +1 -1
  207. package/create-fluxstack.ts +8 -7
  208. package/package.json +12 -13
  209. package/plugins/crypto-auth/cli/make-protected-route.command.ts +1 -1
  210. package/plugins/crypto-auth/client/CryptoAuthClient.ts +302 -302
  211. package/plugins/crypto-auth/client/components/index.ts +11 -11
  212. package/plugins/crypto-auth/client/index.ts +11 -11
  213. package/plugins/crypto-auth/config/index.ts +1 -1
  214. package/plugins/crypto-auth/index.ts +4 -4
  215. package/plugins/crypto-auth/package.json +65 -65
  216. package/plugins/crypto-auth/server/AuthMiddleware.ts +1 -1
  217. package/plugins/crypto-auth/server/CryptoAuthService.ts +185 -185
  218. package/plugins/crypto-auth/server/index.ts +21 -21
  219. package/plugins/crypto-auth/server/middlewares/cryptoAuthAdmin.ts +3 -3
  220. package/plugins/crypto-auth/server/middlewares/cryptoAuthOptional.ts +1 -1
  221. package/plugins/crypto-auth/server/middlewares/cryptoAuthPermissions.ts +2 -2
  222. package/plugins/crypto-auth/server/middlewares/cryptoAuthRequired.ts +2 -2
  223. package/plugins/crypto-auth/server/middlewares/helpers.ts +1 -1
  224. package/plugins/crypto-auth/server/middlewares/index.ts +22 -22
  225. package/tsconfig.api-strict.json +16 -0
  226. package/tsconfig.json +48 -52
  227. package/{app/client/tsconfig.node.json → tsconfig.node.json} +25 -25
  228. package/types/global.d.ts +29 -29
  229. package/types/vitest.d.ts +8 -8
  230. package/vite.config.ts +38 -62
  231. package/vitest.config.live.ts +10 -9
  232. package/vitest.config.ts +29 -17
  233. package/app/client/README.md +0 -69
  234. package/app/client/SIMPLIFICATION.md +0 -140
  235. package/app/client/frontend-only.ts +0 -12
  236. package/app/client/src/live/FileUploadExample.tsx +0 -359
  237. package/app/client/src/live/MinimalLiveClock.tsx +0 -47
  238. package/app/client/src/live/QuickUploadTest.tsx +0 -193
  239. package/app/client/tsconfig.app.json +0 -45
  240. package/app/client/tsconfig.json +0 -7
  241. package/app/client/zustand-setup.md +0 -65
  242. package/app/server/backend-only.ts +0 -18
  243. package/app/server/live/LiveClockComponent.ts +0 -215
  244. package/app/server/live/LiveFileUploadComponent.ts +0 -77
  245. package/app/server/routes/env-test.ts +0 -110
  246. package/core/client/hooks/index.ts +0 -7
  247. package/core/client/hooks/useHybridLiveComponent.ts +0 -685
  248. package/core/client/hooks/useTypedLiveComponent.ts +0 -133
  249. package/core/client/hooks/useWebSocket.ts +0 -361
  250. package/core/config/env.ts +0 -546
  251. package/core/config/loader.ts +0 -522
  252. package/core/config/runtime-config.ts +0 -327
  253. package/core/config/validator.ts +0 -540
  254. package/core/server/backend-entry.ts +0 -51
  255. package/core/server/standalone.ts +0 -106
  256. package/core/utils/regenerate-files.ts +0 -69
  257. package/fluxstack.config.ts +0 -354
@@ -1,132 +1,132 @@
1
- /**
2
- * FluxStack Client Framework Utilities
3
- * Provides client-side utilities and integrations
4
- */
5
-
6
- import type { FluxStackConfig } from "../types"
7
-
8
- export interface ClientFrameworkOptions {
9
- config: FluxStackConfig
10
- baseUrl?: string
11
- timeout?: number
12
- retries?: number
13
- }
14
-
15
- export class FluxStackClient {
16
- private config: FluxStackConfig
17
- private baseUrl: string
18
- private timeout: number
19
- private retries: number
20
-
21
- constructor(options: ClientFrameworkOptions) {
22
- this.config = options.config
23
- this.baseUrl = options.baseUrl || `http://localhost:${options.config.server.port}`
24
- this.timeout = options.timeout || 10000
25
- this.retries = options.retries || 3
26
- }
27
-
28
- // Create a configured fetch client
29
- createFetchClient() {
30
- return async (url: string, options: RequestInit = {}) => {
31
- const fullUrl = url.startsWith('http') ? url : `${this.baseUrl}${url}`
32
-
33
- const requestOptions: RequestInit = {
34
- ...options,
35
- headers: {
36
- 'Content-Type': 'application/json',
37
- ...options.headers
38
- }
39
- }
40
-
41
- // Add timeout
42
- const controller = new AbortController()
43
- const timeoutId = setTimeout(() => controller.abort(), this.timeout)
44
- requestOptions.signal = controller.signal
45
-
46
- try {
47
- const response = await fetch(fullUrl, requestOptions)
48
- clearTimeout(timeoutId)
49
-
50
- if (!response.ok) {
51
- throw new Error(`HTTP ${response.status}: ${response.statusText}`)
52
- }
53
-
54
- return response
55
- } catch (error) {
56
- clearTimeout(timeoutId)
57
- throw error
58
- }
59
- }
60
- }
61
-
62
- // Create API client with retry logic
63
- createApiClient() {
64
- const fetchClient = this.createFetchClient()
65
-
66
- return {
67
- get: async <T>(url: string): Promise<T> => {
68
- return this.withRetry(async () => {
69
- const response = await fetchClient(url, { method: 'GET' })
70
- return response.json()
71
- })
72
- },
73
-
74
- post: async <T>(url: string, data: any): Promise<T> => {
75
- return this.withRetry(async () => {
76
- const response = await fetchClient(url, {
77
- method: 'POST',
78
- body: JSON.stringify(data)
79
- })
80
- return response.json()
81
- })
82
- },
83
-
84
- put: async <T>(url: string, data: any): Promise<T> => {
85
- return this.withRetry(async () => {
86
- const response = await fetchClient(url, {
87
- method: 'PUT',
88
- body: JSON.stringify(data)
89
- })
90
- return response.json()
91
- })
92
- },
93
-
94
- delete: async <T>(url: string): Promise<T> => {
95
- return this.withRetry(async () => {
96
- const response = await fetchClient(url, { method: 'DELETE' })
97
- return response.json()
98
- })
99
- }
100
- }
101
- }
102
-
103
- private async withRetry<T>(fn: () => Promise<T>): Promise<T> {
104
- let lastError: Error
105
-
106
- for (let attempt = 1; attempt <= this.retries; attempt++) {
107
- try {
108
- return await fn()
109
- } catch (error) {
110
- lastError = error as Error
111
-
112
- if (attempt === this.retries) {
113
- throw lastError
114
- }
115
-
116
- // Exponential backoff
117
- const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000)
118
- await new Promise(resolve => setTimeout(resolve, delay))
119
- }
120
- }
121
-
122
- throw lastError!
123
- }
124
-
125
- getConfig(): FluxStackConfig {
126
- return this.config
127
- }
128
-
129
- getBaseUrl(): string {
130
- return this.baseUrl
131
- }
1
+ /**
2
+ * FluxStack Client Framework Utilities
3
+ * Provides client-side utilities and integrations
4
+ */
5
+
6
+ import type { FluxStackConfig } from "../types"
7
+
8
+ export interface ClientFrameworkOptions {
9
+ config: FluxStackConfig
10
+ baseUrl?: string
11
+ timeout?: number
12
+ retries?: number
13
+ }
14
+
15
+ export class FluxStackClient {
16
+ private config: FluxStackConfig
17
+ private baseUrl: string
18
+ private timeout: number
19
+ private retries: number
20
+
21
+ constructor(options: ClientFrameworkOptions) {
22
+ this.config = options.config
23
+ this.baseUrl = options.baseUrl || `http://localhost:${options.config.server.port}`
24
+ this.timeout = options.timeout || 10000
25
+ this.retries = options.retries || 3
26
+ }
27
+
28
+ // Create a configured fetch client
29
+ createFetchClient() {
30
+ return async (url: string, options: RequestInit = {}) => {
31
+ const fullUrl = url.startsWith('http') ? url : `${this.baseUrl}${url}`
32
+
33
+ const requestOptions: RequestInit = {
34
+ ...options,
35
+ headers: {
36
+ 'Content-Type': 'application/json',
37
+ ...options.headers
38
+ }
39
+ }
40
+
41
+ // Add timeout
42
+ const controller = new AbortController()
43
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout)
44
+ requestOptions.signal = controller.signal
45
+
46
+ try {
47
+ const response = await fetch(fullUrl, requestOptions)
48
+ clearTimeout(timeoutId)
49
+
50
+ if (!response.ok) {
51
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`)
52
+ }
53
+
54
+ return response
55
+ } catch (error) {
56
+ clearTimeout(timeoutId)
57
+ throw error
58
+ }
59
+ }
60
+ }
61
+
62
+ // Create API client with retry logic
63
+ createApiClient() {
64
+ const fetchClient = this.createFetchClient()
65
+
66
+ return {
67
+ get: async <T>(url: string): Promise<T> => {
68
+ return this.withRetry(async () => {
69
+ const response = await fetchClient(url, { method: 'GET' })
70
+ return response.json()
71
+ })
72
+ },
73
+
74
+ post: async <T>(url: string, data: any): Promise<T> => {
75
+ return this.withRetry(async () => {
76
+ const response = await fetchClient(url, {
77
+ method: 'POST',
78
+ body: JSON.stringify(data)
79
+ })
80
+ return response.json()
81
+ })
82
+ },
83
+
84
+ put: async <T>(url: string, data: any): Promise<T> => {
85
+ return this.withRetry(async () => {
86
+ const response = await fetchClient(url, {
87
+ method: 'PUT',
88
+ body: JSON.stringify(data)
89
+ })
90
+ return response.json()
91
+ })
92
+ },
93
+
94
+ delete: async <T>(url: string): Promise<T> => {
95
+ return this.withRetry(async () => {
96
+ const response = await fetchClient(url, { method: 'DELETE' })
97
+ return response.json()
98
+ })
99
+ }
100
+ }
101
+ }
102
+
103
+ private async withRetry<T>(fn: () => Promise<T>): Promise<T> {
104
+ let lastError: Error
105
+
106
+ for (let attempt = 1; attempt <= this.retries; attempt++) {
107
+ try {
108
+ return await fn()
109
+ } catch (error) {
110
+ lastError = error as Error
111
+
112
+ if (attempt === this.retries) {
113
+ throw lastError
114
+ }
115
+
116
+ // Exponential backoff
117
+ const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000)
118
+ await new Promise(resolve => setTimeout(resolve, delay))
119
+ }
120
+ }
121
+
122
+ throw lastError!
123
+ }
124
+
125
+ getConfig(): FluxStackConfig {
126
+ return this.config
127
+ }
128
+
129
+ getBaseUrl(): string {
130
+ return this.baseUrl
131
+ }
132
132
  }
@@ -1,8 +1,8 @@
1
- /**
2
- * FluxStack Framework Core
3
- * Main exports for the framework components
4
- */
5
-
6
- export { FluxStackFramework } from "./server"
7
- export { FluxStackClient } from "./client"
1
+ /**
2
+ * FluxStack Framework Core
3
+ * Main exports for the framework components
4
+ */
5
+
6
+ export { FluxStackFramework } from "./server"
7
+ export { FluxStackClient } from "./client"
8
8
  export * from "./types"
@@ -1,15 +1,16 @@
1
1
  import { Elysia } from "elysia"
2
- import type { FluxStackConfig, FluxStackContext } from "@/core/types"
3
- import type { FluxStack, PluginContext, PluginUtils } from "@/core/plugins/types"
4
- import { PluginRegistry } from "@/core/plugins/registry"
5
- import { PluginManager } from "@/core/plugins/manager"
6
- import { getConfigSync, getEnvironmentInfo } from "@/core/config"
7
- import { logger } from "@/core/utils/logger"
8
- import { displayStartupBanner, type StartupInfo } from "@/core/utils/logger/startup-banner"
9
- import { componentRegistry } from "@/core/server/live/ComponentRegistry"
10
- import { createErrorHandler } from "@/core/utils/errors/handlers"
11
- import { createTimer, formatBytes, isProduction, isDevelopment } from "@/core/utils/helpers"
12
- import type { Plugin } from "@/core/plugins"
2
+ import type { FluxStackConfig, FluxStackContext } from "@core/types"
3
+ import type { FluxStack, PluginContext, PluginUtils } from "@core/plugins/types"
4
+ import { PluginRegistry } from "@core/plugins/registry"
5
+ import { PluginManager } from "@core/plugins/manager"
6
+ import { fluxStackConfig } from "@config"
7
+ import { getEnvironmentInfo } from "@core/config"
8
+ import { logger } from "@core/utils/logger"
9
+ import { displayStartupBanner, type StartupInfo } from "@core/utils/logger/startup-banner"
10
+ import { componentRegistry } from "@core/server/live/ComponentRegistry"
11
+ import { FluxStackError } from "@core/utils/errors"
12
+ import { createTimer, formatBytes, isProduction, isDevelopment } from "@core/utils/helpers"
13
+ import type { Plugin } from "@core/plugins"
13
14
 
14
15
  export class FluxStackFramework {
15
16
  private app: Elysia
@@ -37,7 +38,7 @@ export class FluxStackFramework {
37
38
 
38
39
  constructor(config?: Partial<FluxStackConfig>) {
39
40
  // Load the full configuration
40
- const fullConfig = config ? { ...getConfigSync(), ...config } : getConfigSync()
41
+ const fullConfig = config ? { ...fluxStackConfig, ...config } : fluxStackConfig
41
42
  const envInfo = getEnvironmentInfo()
42
43
 
43
44
  this.context = {
@@ -203,7 +204,7 @@ export class FluxStackFramework {
203
204
  }
204
205
 
205
206
  private setupCors() {
206
- const { cors } = this.context.config.server
207
+ const cors = this.context.config.cors
207
208
 
208
209
  this.app
209
210
  .onRequest(({ set }) => {
@@ -283,9 +284,9 @@ export class FluxStackFramework {
283
284
 
284
285
  // Pass through all other stderr output
285
286
  if (typeof encoding === 'function') {
286
- return originalStderrWrite.call(process.stderr, chunk, encoding)
287
+ return (originalStderrWrite as Function).call(process.stderr, chunk, encoding)
287
288
  } else {
288
- return originalStderrWrite.call(process.stderr, chunk, encoding, callback)
289
+ return (originalStderrWrite as Function).call(process.stderr, chunk, encoding, callback)
289
290
  }
290
291
  }
291
292
 
@@ -450,47 +451,53 @@ export class FluxStackFramework {
450
451
  }
451
452
 
452
453
  private setupErrorHandling() {
453
- const errorHandler = createErrorHandler({
454
- logger: this.pluginContext.logger,
455
- isDevelopment: this.context.isDevelopment
456
- })
457
-
458
- this.app.onError(async ({ error, request, path, set }) => {
459
- const startTime = Date.now()
454
+ this.app.onError(async ({ error, request, code, set }) => {
460
455
  const url = this.parseRequestURL(request)
461
456
 
457
+ // Let plugins handle errors first (e.g. Vite SPA fallback)
462
458
  const errorContext = {
463
459
  request,
464
460
  path: url.pathname,
465
461
  method: request.method,
466
- headers: (() => {
467
- const headers: Record<string, string> = {}
468
- request.headers.forEach((value: string, key: string) => {
469
- headers[key] = value
470
- })
471
- return headers
472
- })(),
473
- query: Object.fromEntries(url.searchParams.entries()),
474
- params: {},
475
462
  error: error instanceof Error ? error : new Error(String(error)),
476
- duration: Date.now() - startTime,
477
463
  handled: false,
478
- startTime
464
+ startTime: Date.now()
479
465
  }
480
466
 
481
- // Execute onError hooks for all plugins - allow them to handle the error
482
467
  const handledResponse = await this.executePluginErrorHooks(errorContext)
483
-
484
- // If a plugin handled the error, return the response
485
468
  if (handledResponse) {
486
469
  return handledResponse
487
470
  }
488
471
 
489
- // Vite proxy logic is now handled by the Vite plugin via onBeforeRoute hook
472
+ // For Elysia's own errors (validation, not found, parse), let them pass through
473
+ // Elysia sets proper status codes and messages natively
474
+ if (code === 'VALIDATION' || code === 'PARSE' || code === 'NOT_FOUND') {
475
+ return
476
+ }
490
477
 
491
- // Convert Elysia error to standard Error if needed
492
- const standardError = error instanceof Error ? error : new Error(String(error))
493
- return errorHandler(standardError, request, path)
478
+ // For FluxStackErrors, use their status code and message
479
+ if (error instanceof FluxStackError) {
480
+ set.status = error.statusCode
481
+ return {
482
+ error: error.code,
483
+ message: error.userMessage || error.message,
484
+ ...(this.context.isDevelopment && { stack: error.stack })
485
+ }
486
+ }
487
+
488
+ // Log unexpected errors (actual 500s)
489
+ logger.error(`Unhandled error: ${error instanceof Error ? error.message : String(error)}`, {
490
+ path: url.pathname,
491
+ method: request.method
492
+ })
493
+
494
+ set.status = 500
495
+ return {
496
+ error: 'INTERNAL_SERVER_ERROR',
497
+ message: this.context.isDevelopment
498
+ ? (error instanceof Error ? error.message : String(error))
499
+ : 'An unexpected error occurred'
500
+ }
494
501
  })
495
502
  }
496
503
 
@@ -3,8 +3,8 @@
3
3
  * Defines the main interfaces and types for the FluxStack framework
4
4
  */
5
5
 
6
- import type { FluxStackConfig } from "@/core/types"
7
- import type { Logger } from "@/core/utils/logger/index"
6
+ import type { FluxStackConfig } from "@core/types"
7
+ import type { Logger } from "@core/utils/logger/index"
8
8
 
9
9
  export interface FluxStackFrameworkOptions {
10
10
  config?: Partial<FluxStackConfig>
package/core/index.ts CHANGED
@@ -28,9 +28,28 @@ export { PluginDiscovery, pluginDiscovery } from './plugins/discovery'
28
28
  export { PluginManager } from './plugins/manager'
29
29
  export { PluginUtils } from './plugins'
30
30
 
31
- // Utilities
32
- export * from './utils/logger'
33
- // Note: errors are already exported via ./server (BuildError), avoid duplicate export
31
+ // Utilities (avoid wildcard export to prevent type duplication)
32
+ export {
33
+ LOGGER_CONFIG,
34
+ LOG,
35
+ WARN,
36
+ ERROR,
37
+ DEBUG,
38
+ START,
39
+ SUCCESS,
40
+ IMPORTANT,
41
+ SECTION,
42
+ request as logRequest,
43
+ plugin as logPlugin,
44
+ framework as logFramework,
45
+ time as logTime,
46
+ timeEnd as logTimeEnd,
47
+ clearCache as clearLoggerCache,
48
+ logger,
49
+ log
50
+ } from './utils/logger'
51
+ export type { Logger } from './utils/logger'
52
+ // Note: BuildError types already exported via ./server
34
53
 
35
54
  // Version
36
- export { FLUXSTACK_VERSION } from './utils/version'
55
+ export { FLUXSTACK_VERSION } from './utils/version'
@@ -6,7 +6,7 @@ import type {
6
6
  BroadcastMessage,
7
7
  ComponentDefinition,
8
8
  WebSocketData
9
- } from '@/core/types/types'
9
+ } from '@core/types/types'
10
10
 
11
11
  export class ComponentRegistry {
12
12
  private components = new Map<string, LiveComponent>()
@@ -17,7 +17,7 @@ export class ComponentRegistry {
17
17
 
18
18
  // Register component definition
19
19
  registerComponent<TState>(definition: ComponentDefinition<TState>) {
20
- this.definitions.set(definition.name, definition)
20
+ this.definitions.set(definition.name, definition as unknown as ComponentDefinition)
21
21
  console.log(`📝 Registered component: ${definition.name}`)
22
22
  }
23
23
 
@@ -35,7 +35,7 @@ export class ComponentRegistry {
35
35
 
36
36
  if (!fs.existsSync(componentsPath)) {
37
37
  // In production, components are already bundled - no need to auto-discover
38
- const { appConfig } = await import('@/config/app.config')
38
+ const { appConfig } = await import('@config')
39
39
  if (appConfig.env !== 'production') {
40
40
  console.log(`⚠️ Components path not found: ${componentsPath}`)
41
41
  }
@@ -150,6 +150,83 @@ export abstract class LiveComponent<TState = ComponentState> {
150
150
  public getSerializableState(): TState {
151
151
  return this.state
152
152
  }
153
+
154
+ // ===== Livewire-style Actions =====
155
+ // These are automatically available for all LiveComponents
156
+ // Used by useLivewire() hook for transparent property access
157
+
158
+ /**
159
+ * Set a single state property value
160
+ * Used by useLivewire() proxy for transparent property assignment
161
+ *
162
+ * @example
163
+ * // Frontend with useLivewire:
164
+ * clock.format = '12h' // Automatically calls setValue({ key: 'format', value: '12h' })
165
+ */
166
+ async setValue<K extends keyof TState>(payload: { key: K; value: TState[K] }): Promise<{ success: boolean; key: K; value: TState[K] }> {
167
+ const { key, value } = payload
168
+
169
+ // Validate that the key exists in state
170
+ const stateObj = this.state as Record<string, unknown>
171
+ if (!(String(key) in stateObj)) {
172
+ throw new Error(`Property '${String(key)}' does not exist in component state`)
173
+ }
174
+
175
+ this.setState({ [key]: value } as unknown as Partial<TState>)
176
+
177
+ return { success: true, key, value }
178
+ }
179
+
180
+ /**
181
+ * Set multiple state properties at once
182
+ * Useful for batch updates
183
+ *
184
+ * @example
185
+ * await clock.$call('setValues', { format: '12h', showSeconds: false })
186
+ */
187
+ async setValues(payload: Partial<TState>): Promise<{ success: boolean; updated: (keyof TState)[] }> {
188
+ const stateObj = this.state as Record<string, unknown>
189
+ const validKeys = Object.keys(payload).filter(key => key in stateObj) as (keyof TState)[]
190
+
191
+ if (validKeys.length === 0) {
192
+ throw new Error('No valid properties to update')
193
+ }
194
+
195
+ const updates = validKeys.reduce((acc, key) => {
196
+ acc[key] = payload[key] as TState[keyof TState]
197
+ return acc
198
+ }, {} as Partial<TState>)
199
+
200
+ this.setState(updates)
201
+
202
+ return { success: true, updated: validKeys }
203
+ }
204
+
205
+ /**
206
+ * Get a single state property value
207
+ * Useful for getting computed/derived values from server
208
+ */
209
+ async getValue<K extends keyof TState>(payload: { key: K }): Promise<{ success: boolean; key: K; value: TState[K] }> {
210
+ const { key } = payload
211
+
212
+ const stateObj = this.state as Record<string, unknown>
213
+ if (!(String(key) in stateObj)) {
214
+ throw new Error(`Property '${String(key)}' does not exist in component state`)
215
+ }
216
+
217
+ return { success: true, key, value: this.state[key] }
218
+ }
219
+
220
+ /**
221
+ * Get all state values (snapshot)
222
+ */
223
+ async getSnapshot(): Promise<{ success: boolean; state: TState; timestamp: number }> {
224
+ return {
225
+ success: true,
226
+ state: this.getSerializableState(),
227
+ timestamp: Date.now()
228
+ }
229
+ }
153
230
  }
154
231
 
155
232
  // Utility types for better TypeScript experience