create-fluxstack 1.16.0 โ†’ 1.17.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 (119) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/app/client/src/App.tsx +8 -0
  3. package/app/client/src/live/AuthDemo.tsx +4 -4
  4. package/core/build/bundler.ts +40 -26
  5. package/core/build/flux-plugins-generator.ts +325 -325
  6. package/core/build/index.ts +92 -21
  7. package/core/cli/command-registry.ts +44 -46
  8. package/core/cli/commands/build.ts +11 -6
  9. package/core/cli/commands/create.ts +7 -5
  10. package/core/cli/commands/dev.ts +6 -5
  11. package/core/cli/commands/help.ts +3 -2
  12. package/core/cli/commands/make-plugin.ts +8 -7
  13. package/core/cli/commands/plugin-add.ts +60 -43
  14. package/core/cli/commands/plugin-deps.ts +73 -57
  15. package/core/cli/commands/plugin-list.ts +44 -41
  16. package/core/cli/commands/plugin-remove.ts +33 -22
  17. package/core/cli/generators/component.ts +770 -769
  18. package/core/cli/generators/controller.ts +9 -8
  19. package/core/cli/generators/index.ts +148 -146
  20. package/core/cli/generators/interactive.ts +228 -227
  21. package/core/cli/generators/plugin.ts +11 -10
  22. package/core/cli/generators/prompts.ts +83 -82
  23. package/core/cli/generators/route.ts +7 -6
  24. package/core/cli/generators/service.ts +10 -9
  25. package/core/cli/generators/template-engine.ts +2 -1
  26. package/core/cli/generators/types.ts +7 -7
  27. package/core/cli/generators/utils.ts +191 -191
  28. package/core/cli/index.ts +9 -8
  29. package/core/cli/plugin-discovery.ts +2 -2
  30. package/core/client/hooks/useAuth.ts +48 -48
  31. package/core/client/standalone.ts +18 -17
  32. package/core/client/state/createStore.ts +192 -192
  33. package/core/client/state/index.ts +14 -14
  34. package/core/config/index.ts +1 -0
  35. package/core/framework/client.ts +131 -131
  36. package/core/framework/index.ts +7 -7
  37. package/core/framework/server.ts +72 -112
  38. package/core/framework/types.ts +2 -2
  39. package/core/plugins/built-in/live-components/commands/create-live-component.ts +6 -3
  40. package/core/plugins/built-in/monitoring/index.ts +110 -68
  41. package/core/plugins/built-in/static/index.ts +2 -2
  42. package/core/plugins/built-in/swagger/index.ts +9 -9
  43. package/core/plugins/built-in/vite/index.ts +3 -3
  44. package/core/plugins/built-in/vite/vite-dev.ts +3 -3
  45. package/core/plugins/config.ts +50 -47
  46. package/core/plugins/discovery.ts +10 -4
  47. package/core/plugins/executor.ts +2 -2
  48. package/core/plugins/index.ts +206 -203
  49. package/core/plugins/manager.ts +21 -20
  50. package/core/plugins/registry.ts +76 -12
  51. package/core/plugins/types.ts +14 -14
  52. package/core/server/framework.ts +3 -189
  53. package/core/server/live/auto-generated-components.ts +11 -29
  54. package/core/server/live/index.ts +41 -31
  55. package/core/server/live/websocket-plugin.ts +11 -1
  56. package/core/server/middleware/elysia-helpers.ts +16 -15
  57. package/core/server/middleware/errorHandling.ts +14 -14
  58. package/core/server/middleware/index.ts +31 -31
  59. package/core/server/plugins/database.ts +181 -180
  60. package/core/server/plugins/static-files-plugin.ts +4 -3
  61. package/core/server/plugins/swagger.ts +11 -8
  62. package/core/server/rooms/RoomBroadcaster.ts +11 -10
  63. package/core/server/rooms/RoomSystem.ts +14 -11
  64. package/core/server/services/BaseService.ts +7 -7
  65. package/core/server/services/ServiceContainer.ts +5 -5
  66. package/core/server/services/index.ts +8 -8
  67. package/core/templates/create-project.ts +28 -27
  68. package/core/testing/index.ts +9 -9
  69. package/core/testing/setup.ts +73 -73
  70. package/core/types/api.ts +168 -168
  71. package/core/types/config.ts +5 -5
  72. package/core/types/index.ts +1 -1
  73. package/core/types/plugin.ts +2 -2
  74. package/core/types/types.ts +3 -3
  75. package/core/utils/build-logger.ts +324 -324
  76. package/core/utils/config-schema.ts +480 -480
  77. package/core/utils/env.ts +10 -8
  78. package/core/utils/errors/codes.ts +114 -114
  79. package/core/utils/errors/handlers.ts +30 -20
  80. package/core/utils/errors/index.ts +54 -46
  81. package/core/utils/errors/middleware.ts +113 -113
  82. package/core/utils/helpers.ts +19 -16
  83. package/core/utils/logger/colors.ts +114 -114
  84. package/core/utils/logger/config.ts +2 -2
  85. package/core/utils/logger/formatter.ts +82 -82
  86. package/core/utils/logger/group-logger.ts +101 -101
  87. package/core/utils/logger/index.ts +13 -3
  88. package/core/utils/logger/startup-banner.ts +2 -2
  89. package/core/utils/logger/winston-logger.ts +152 -152
  90. package/core/utils/monitoring/index.ts +211 -211
  91. package/core/utils/sync-version.ts +67 -66
  92. package/core/utils/version.ts +1 -1
  93. package/package.json +104 -100
  94. package/playwright-report/index.html +85 -0
  95. package/playwright.config.ts +31 -0
  96. package/plugins/crypto-auth/client/CryptoAuthClient.ts +302 -302
  97. package/plugins/crypto-auth/client/components/index.ts +11 -11
  98. package/plugins/crypto-auth/client/index.ts +11 -11
  99. package/plugins/crypto-auth/package.json +65 -65
  100. package/plugins/crypto-auth/server/CryptoAuthService.ts +185 -185
  101. package/plugins/crypto-auth/server/middlewares/cryptoAuthAdmin.ts +6 -5
  102. package/plugins/crypto-auth/server/middlewares/cryptoAuthPermissions.ts +6 -5
  103. package/plugins/crypto-auth/server/middlewares/cryptoAuthRequired.ts +3 -3
  104. package/plugins/crypto-auth/server/middlewares/index.ts +22 -22
  105. package/plugins/crypto-auth/server/middlewares.ts +19 -19
  106. package/vite.config.ts +13 -0
  107. package/app/client/.live-stubs/LiveAdminPanel.js +0 -5
  108. package/app/client/.live-stubs/LiveCounter.js +0 -9
  109. package/app/client/.live-stubs/LiveForm.js +0 -11
  110. package/app/client/.live-stubs/LiveLocalCounter.js +0 -8
  111. package/app/client/.live-stubs/LivePingPong.js +0 -10
  112. package/app/client/.live-stubs/LiveRoomChat.js +0 -11
  113. package/app/client/.live-stubs/LiveSharedCounter.js +0 -10
  114. package/app/client/.live-stubs/LiveUpload.js +0 -15
  115. package/app/server/live/register-components.ts +0 -19
  116. package/core/build/live-components-generator.ts +0 -321
  117. package/core/live/ComponentRegistry.ts +0 -403
  118. package/core/live/types.ts +0 -241
  119. package/workspace.json +0 -6
package/CHANGELOG.md ADDED
@@ -0,0 +1,80 @@
1
+ # Changelog
2
+
3
+ All notable changes to FluxStack will be documented in this file.
4
+
5
+ ## [1.16.0] - 2026-03-13
6
+
7
+ ### Major Refactor: Extract Live Components to Monorepo
8
+
9
+ Live Components code has been extracted from `core/` into standalone npm packages under the `@fluxstack/live` scope. This reduces the framework core by ~11,000 lines and allows the Live system to be versioned and published independently.
10
+
11
+ ### Changed
12
+
13
+ - **Live Components are now npm packages**: `@fluxstack/live`, `@fluxstack/live-client`, `@fluxstack/live-react`, `@fluxstack/live-elysia`
14
+ - `core/server/live/` reduced from full implementation to thin re-exports from `@fluxstack/live` and `@fluxstack/live-elysia`
15
+ - `core/client/` reduced from full implementation to re-exports from `@fluxstack/live-client` and `@fluxstack/live-react`
16
+ - Vite config now includes source aliases for `@fluxstack/live`, `@fluxstack/live-client`, and `@fluxstack/live-react` (frontend dev uses TypeScript source directly)
17
+ - Tests migrated to v0.3.0 API: `setLiveComponentContext` DI pattern replaces `vi.mock`, async flush for `WsSendBatcher`
18
+ - CI Bun version updated to 1.3.2
19
+
20
+ ### Added
21
+
22
+ - Typed LiveRoom demos: `LivePingPong`, `LiveSharedCounter` with dedicated Room classes (`ChatRoom`, `CounterRoom`, `DirectoryRoom`, `PingRoom`)
23
+ - `PingPongDemo.tsx`, `SharedCounterDemo.tsx` โ€” new frontend demo components
24
+ - `LLMD/resources/live-binary-delta.md` โ€” binary delta codec documentation
25
+ - `plugins/*/bun.lock` added to `.gitignore`
26
+ - Bundler now logs stdout/stderr on build failure for CI debugging
27
+
28
+ ### Removed
29
+
30
+ - `core/server/live/ComponentRegistry.ts`, `WebSocketConnectionManager.ts`, `StateSignature.ts`, `LiveRoomManager.ts`, `RoomEventBus.ts`, `RoomStateManager.ts`, `FileUploadManager.ts`, `LiveComponentPerformanceMonitor.ts`, `LiveDebugger.ts`, `LiveLogger.ts` โ€” moved to `@fluxstack/live`
31
+ - `core/server/live/auth/` โ€” moved to `@fluxstack/live`
32
+ - `core/server/live/__tests__/` โ€” moved to `fluxstack-live` monorepo
33
+ - `core/client/LiveComponentsProvider.tsx`, `Live.tsx`, `LiveDebugger.tsx` โ€” moved to `@fluxstack/live-react`
34
+ - `core/client/hooks/useLiveComponent.ts`, `useRoom.ts`, `useRoomProxy.ts`, `useLiveDebugger.ts`, `useChunkedUpload.ts`, `useLiveChunkedUpload.ts`, `AdaptiveChunkSizer.ts`, `state-validator.ts` โ€” moved to `@fluxstack/live-client`
35
+ - `core/build/vite-plugin-live-strip.ts` โ€” moved to `@fluxstack/live`
36
+ - `LiveDebugger` UI and exports (removed entirely, not extracted)
37
+ - `LiveChat` and `LiveTodoList` demo components (replaced by new typed demos)
38
+ - `ChatDemo.tsx`, `TodoListDemo.tsx`, `LiveDebuggerPanel.tsx` โ€” replaced by new demos
39
+ - `workspace.json` โ€” stale config referencing non-existent `./packages/*`
40
+
41
+ ### Fixed
42
+
43
+ - Bun bundler failing on Linux CI with `"Could not resolve: @fluxstack/live"` โ€” caused by `"bun"` export condition in `@fluxstack/live@0.3.0` pointing to non-existent `src/` (fixed in `@fluxstack/live@0.3.1`)
44
+ - `live-components-generator.ts` basename extraction bug
45
+ - Vite aliases made conditional for CI compatibility
46
+
47
+ ---
48
+
49
+ ## [1.14.0] - 2026-02-15
50
+
51
+ ### Security
52
+
53
+ - Harden Live Components against critical vulnerabilities: action whitelist enforcement, state prototype pollution guard, WebSocket message size limits, rate limiting
54
+ - Add `$private` server-only state with `TPrivate` generic for type-safe private data
55
+ - `ExtractActions` type now respects `publicActions` whitelist
56
+ - Harden static-files plugin with security headers, path traversal protection, streaming support
57
+
58
+ ### Added
59
+
60
+ - **Live Component Debugger**: draggable floating window for real-time component inspection with rooms tab, collapsible JSON tree, settings panel (font size, compact mode, word wrap)
61
+ - Server-controlled debug activation (`DEBUG_LIVE` env var, defaults to `false`)
62
+ - Live component logs forwarded to debug panel as `LOG` events
63
+ - Two-channel logging architecture (LiveLogger for structured logs)
64
+ - Dynamic favicon and page title that change per route
65
+ - FluxStack logo in navbar with route-based hue shift and Live Docs button
66
+ - Mobile responsive layout with floating logo and adaptive sizing
67
+
68
+ ### Fixed
69
+
70
+ - Prevent LiveDebugger from being imported in client-side bundle
71
+ - Normalize path separators in static file serving on Windows
72
+ - Handle undefined type from reactive config with nullish coalesce
73
+ - `setValue` added to `LiveForm.publicActions` to enable `$field()` sync
74
+ - Preserve active tab when selecting component in debugger
75
+ - Stop click propagation on expanded event details
76
+
77
+ ### Changed
78
+
79
+ - Static-files plugin refactored to use Bun-native APIs instead of Node `fs`
80
+ - Debug config read from FluxStack config system instead of raw env vars
@@ -157,8 +157,16 @@ function AppContent() {
157
157
  }
158
158
 
159
159
  function App() {
160
+ // In dev, connect WebSocket directly to backend (port 3000) to avoid
161
+ // Vite proxy overhead and HMR WebSocket contention on port 5173.
162
+ // In production, both are served from the same origin so auto-detect works.
163
+ const wsUrl = import.meta.env.DEV
164
+ ? 'ws://localhost:3000/api/live/ws'
165
+ : undefined
166
+
160
167
  return (
161
168
  <LiveComponentsProvider
169
+ url={wsUrl}
162
170
  autoConnect={true}
163
171
  reconnectInterval={1000}
164
172
  maxReconnectAttempts={5}
@@ -126,7 +126,7 @@ function AdminSection() {
126
126
  User: <span className="text-emerald-300">{panel.$state.currentUser || '...'}</span>
127
127
  </div>
128
128
  <div className="text-gray-400">
129
- Roles: <span className="text-yellow-300">{panel.$state.currentRoles.join(', ') || '...'}</span>
129
+ Roles: <span className="text-yellow-300">{panel.$state.currentRoles?.join(', ') || '...'}</span>
130
130
  </div>
131
131
  </div>
132
132
  </div>
@@ -139,7 +139,7 @@ function AdminSection() {
139
139
 
140
140
  {/* User list */}
141
141
  <div className="space-y-2 mb-4">
142
- {panel.$state.users.map(user => (
142
+ {(panel.$state.users ?? []).map(user => (
143
143
  <div key={user.id} className="flex items-center justify-between bg-black/20 rounded-lg px-4 py-2">
144
144
  <div>
145
145
  <span className="text-white font-medium">{user.name}</span>
@@ -174,7 +174,7 @@ function AdminSection() {
174
174
  </div>
175
175
 
176
176
  {/* Audit log */}
177
- {panel.$state.audit.length > 0 && (
177
+ {(panel.$state.audit?.length ?? 0) > 0 && (
178
178
  <div className="mt-4 pt-4 border-t border-white/10">
179
179
  <div className="flex items-center justify-between mb-2">
180
180
  <h4 className="text-sm font-semibold text-gray-300">Audit Log</h4>
@@ -187,7 +187,7 @@ function AdminSection() {
187
187
  </button>
188
188
  </div>
189
189
  <div className="space-y-1 max-h-32 overflow-auto">
190
- {panel.$state.audit.map((entry, i) => (
190
+ {(panel.$state.audit ?? []).map((entry, i) => (
191
191
  <div key={i} className="text-xs text-gray-500">
192
192
  <span className="text-gray-400">{new Date(entry.timestamp).toLocaleTimeString()}</span>
193
193
  {' '}<span className="text-blue-300">{entry.action}</span>
@@ -4,6 +4,7 @@ import { join } from "path"
4
4
  import type { FluxStackConfig } from "../config"
5
5
  import type { BundleResult, BundleOptions } from "../types/build"
6
6
  import { buildLogger } from "../utils/build-logger"
7
+ import { generateLiveComponentsFile } from "@fluxstack/live/build"
7
8
 
8
9
  export interface BundlerConfig {
9
10
  target: 'bun' | 'node' | 'docker'
@@ -54,12 +55,15 @@ export class Bundler {
54
55
  assets: await this.getClientAssets()
55
56
  }
56
57
  } else {
58
+ const stdout = await new Response(buildProcess.stdout).text()
57
59
  const stderr = await new Response(buildProcess.stderr).text()
58
60
  buildLogger.error("Client bundle failed")
61
+ if (stdout.trim()) buildLogger.error(`stdout:\n${stdout.trim()}`)
62
+ if (stderr.trim()) buildLogger.error(`stderr:\n${stderr.trim()}`)
59
63
  return {
60
64
  success: false,
61
65
  duration,
62
- error: stderr || "Client build failed"
66
+ error: stderr || stdout || "Client build failed"
63
67
  }
64
68
  }
65
69
  } catch (error) {
@@ -76,11 +80,10 @@ export class Bundler {
76
80
  buildLogger.section('Server Build', 'โšก')
77
81
 
78
82
  const startTime = Date.now()
79
- let liveComponentsGenerator: any = null
80
83
 
81
84
  try {
82
- // Run pre-build steps
83
- liveComponentsGenerator = await this.runPreBuildSteps()
85
+ // Run pre-build steps (component discovery + plugins generation)
86
+ await this.runPreBuildSteps()
84
87
 
85
88
  // Ensure output directory exists
86
89
  this.ensureOutputDirectory()
@@ -120,7 +123,7 @@ export class Bundler {
120
123
  buildLogger.success(`Server bundle completed in ${buildLogger.formatDuration(duration)}`)
121
124
 
122
125
  // Run post-build cleanup
123
- await this.runPostBuildCleanup(liveComponentsGenerator)
126
+ await this.runPostBuildCleanup()
124
127
 
125
128
  return {
126
129
  success: true,
@@ -129,16 +132,20 @@ export class Bundler {
129
132
  entryPoint: join(this.config.outDir, "index.js")
130
133
  }
131
134
  } else {
135
+ const stdout = await new Response(buildProcess.stdout).text()
136
+ const stderr = await new Response(buildProcess.stderr).text()
137
+
132
138
  buildLogger.error("Server bundle failed")
139
+ if (stdout.trim()) buildLogger.error(`stdout:\n${stdout.trim()}`)
140
+ if (stderr.trim()) buildLogger.error(`stderr:\n${stderr.trim()}`)
133
141
 
134
142
  // Run post-build cleanup
135
- await this.runPostBuildCleanup(liveComponentsGenerator)
143
+ await this.runPostBuildCleanup()
136
144
 
137
- const stderr = await new Response(buildProcess.stderr).text()
138
145
  return {
139
146
  success: false,
140
147
  duration,
141
- error: stderr || "Server build failed"
148
+ error: stderr || stdout || "Server build failed"
142
149
  }
143
150
  }
144
151
  } catch (error) {
@@ -146,7 +153,7 @@ export class Bundler {
146
153
 
147
154
  // ๐Ÿงน CLEANUP: Restore original files on error
148
155
  try {
149
- await this.runPostBuildCleanup(liveComponentsGenerator)
156
+ await this.runPostBuildCleanup()
150
157
  } catch (cleanupError) {
151
158
  buildLogger.warn(`Failed to cleanup generated files: ${cleanupError}`)
152
159
  }
@@ -163,11 +170,10 @@ export class Bundler {
163
170
  buildLogger.section('Executable Build', '๐Ÿ“ฆ')
164
171
 
165
172
  const startTime = Date.now()
166
- let liveComponentsGenerator: any = null
167
173
 
168
174
  try {
169
- // Run pre-build steps
170
- liveComponentsGenerator = await this.runPreBuildSteps()
175
+ // Run pre-build steps (component discovery + plugins generation)
176
+ await this.runPreBuildSteps()
171
177
 
172
178
  // Ensure output directory exists
173
179
  this.ensureOutputDirectory()
@@ -248,7 +254,7 @@ export class Bundler {
248
254
  buildLogger.success(`Executable compiled in ${buildLogger.formatDuration(duration)}`)
249
255
 
250
256
  // Run post-build cleanup
251
- await this.runPostBuildCleanup(liveComponentsGenerator)
257
+ await this.runPostBuildCleanup()
252
258
 
253
259
  return {
254
260
  success: true,
@@ -260,7 +266,7 @@ export class Bundler {
260
266
  buildLogger.error("Executable compilation failed")
261
267
 
262
268
  // Run post-build cleanup
263
- await this.runPostBuildCleanup(liveComponentsGenerator)
269
+ await this.runPostBuildCleanup()
264
270
 
265
271
  const stderr = await new Response(buildProcess.stderr).text()
266
272
  return {
@@ -274,7 +280,7 @@ export class Bundler {
274
280
 
275
281
  // ๐Ÿงน CLEANUP: Restore original files on error
276
282
  try {
277
- await this.runPostBuildCleanup(liveComponentsGenerator)
283
+ await this.runPostBuildCleanup()
278
284
  } catch (cleanupError) {
279
285
  buildLogger.warn(`Failed to cleanup generated files: ${cleanupError}`)
280
286
  }
@@ -313,30 +319,38 @@ export class Bundler {
313
319
  }
314
320
 
315
321
  /**
316
- * Run pre-build steps (Live Components and Plugins generation)
322
+ * Run pre-build steps (component discovery + plugins generation)
317
323
  */
318
- private async runPreBuildSteps(): Promise<any> {
324
+ private async runPreBuildSteps(): Promise<void> {
319
325
  // ๐Ÿš€ PRE-BUILD: Auto-generate Live Components registration
320
- const generatorModule = await import('./live-components-generator')
321
- const liveComponentsGenerator = generatorModule.liveComponentsGenerator
322
- await liveComponentsGenerator.preBuild()
326
+ this.discoverLiveComponents()
323
327
 
324
328
  // ๐Ÿ”Œ PRE-BUILD: Auto-generate FluxStack Plugins registration
325
329
  const pluginsGeneratorModule = await import('./flux-plugins-generator')
326
330
  const fluxPluginsGenerator = pluginsGeneratorModule.fluxPluginsGenerator
327
331
  await fluxPluginsGenerator.preBuild()
328
-
329
- return liveComponentsGenerator
330
332
  }
331
333
 
332
334
  /**
333
- * Run post-build cleanup
335
+ * Scan and generate the Live Components registration file.
334
336
  */
335
- private async runPostBuildCleanup(liveComponentsGenerator: any): Promise<void> {
336
- if (liveComponentsGenerator) {
337
- await liveComponentsGenerator.postBuild(false)
337
+ private discoverLiveComponents(): void {
338
+ const count = generateLiveComponentsFile({
339
+ componentsDir: join(process.cwd(), 'app', 'server', 'live'),
340
+ outFile: join(process.cwd(), 'core', 'server', 'live', 'auto-generated-components.ts'),
341
+ importPrefix: '@app/server/live',
342
+ })
343
+ if (count >= 0) {
344
+ buildLogger.success(`Discovered ${count} Live Components`)
345
+ } else {
346
+ buildLogger.warn('No app/server/live/ directory found, skipping component discovery')
338
347
  }
348
+ }
339
349
 
350
+ /**
351
+ * Run post-build cleanup
352
+ */
353
+ private async runPostBuildCleanup(): Promise<void> {
340
354
  const pluginsGeneratorModule = await import('./flux-plugins-generator')
341
355
  const fluxPluginsGenerator = pluginsGeneratorModule.fluxPluginsGenerator
342
356
  await fluxPluginsGenerator.postBuild(false)