create-fluxstack 1.10.1 → 1.12.1
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/.dockerignore +1 -2
- package/Dockerfile +8 -8
- package/LLMD/INDEX.md +64 -0
- package/LLMD/MAINTENANCE.md +197 -0
- package/LLMD/MIGRATION.md +156 -0
- package/LLMD/config/.gitkeep +1 -0
- package/LLMD/config/declarative-system.md +268 -0
- package/LLMD/config/environment-vars.md +327 -0
- package/LLMD/config/runtime-reload.md +401 -0
- package/LLMD/core/.gitkeep +1 -0
- package/LLMD/core/build-system.md +599 -0
- package/LLMD/core/framework-lifecycle.md +229 -0
- package/LLMD/core/plugin-system.md +451 -0
- package/LLMD/patterns/.gitkeep +1 -0
- package/LLMD/patterns/anti-patterns.md +297 -0
- package/LLMD/patterns/project-structure.md +264 -0
- package/LLMD/patterns/type-safety.md +440 -0
- package/LLMD/reference/.gitkeep +1 -0
- package/LLMD/reference/cli-commands.md +250 -0
- package/LLMD/reference/plugin-hooks.md +357 -0
- package/LLMD/reference/routing.md +39 -0
- package/LLMD/reference/troubleshooting.md +364 -0
- package/LLMD/resources/.gitkeep +1 -0
- package/LLMD/resources/controllers.md +465 -0
- package/LLMD/resources/live-components.md +703 -0
- package/LLMD/resources/live-rooms.md +482 -0
- package/LLMD/resources/live-upload.md +130 -0
- package/LLMD/resources/plugins-external.md +617 -0
- package/LLMD/resources/routes-eden.md +254 -0
- package/README.md +37 -17
- package/app/client/index.html +0 -1
- package/app/client/src/App.tsx +107 -150
- package/app/client/src/components/AppLayout.tsx +68 -0
- package/app/client/src/components/BackButton.tsx +13 -0
- package/app/client/src/components/DemoPage.tsx +20 -0
- package/app/client/src/components/LiveUploadWidget.tsx +204 -0
- package/app/client/src/lib/eden-api.ts +85 -60
- package/app/client/src/live/ChatDemo.tsx +107 -0
- package/app/client/src/live/CounterDemo.tsx +206 -0
- package/app/client/src/live/FormDemo.tsx +119 -0
- package/app/client/src/live/RoomChatDemo.tsx +161 -0
- package/app/client/src/live/UploadDemo.tsx +21 -0
- package/app/client/src/main.tsx +4 -1
- package/app/client/src/pages/ApiTestPage.tsx +108 -0
- package/app/client/src/pages/HomePage.tsx +76 -0
- package/app/server/app.ts +1 -4
- package/app/server/controllers/users.controller.ts +36 -44
- package/app/server/index.ts +25 -35
- package/app/server/live/LiveChat.ts +77 -0
- package/app/server/live/LiveCounter.ts +67 -0
- package/app/server/live/LiveForm.ts +63 -0
- package/app/server/live/LiveLocalCounter.ts +32 -0
- package/app/server/live/LiveRoomChat.ts +127 -0
- package/app/server/live/LiveUpload.ts +81 -0
- package/app/server/routes/index.ts +3 -1
- package/app/server/routes/room.routes.ts +117 -0
- package/app/server/routes/users.routes.ts +35 -27
- package/app/shared/types/index.ts +14 -2
- package/config/app.config.ts +2 -62
- package/config/client.config.ts +2 -95
- package/config/database.config.ts +2 -99
- package/config/fluxstack.config.ts +25 -45
- package/config/index.ts +57 -38
- package/config/monitoring.config.ts +2 -114
- package/config/plugins.config.ts +2 -80
- package/config/server.config.ts +2 -68
- package/config/services.config.ts +2 -130
- package/config/system/app.config.ts +29 -0
- package/config/system/build.config.ts +49 -0
- package/config/system/client.config.ts +68 -0
- package/config/system/database.config.ts +17 -0
- package/config/system/fluxstack.config.ts +114 -0
- package/config/{logger.config.ts → system/logger.config.ts} +3 -1
- package/config/system/monitoring.config.ts +114 -0
- package/config/system/plugins.config.ts +84 -0
- package/config/{runtime.config.ts → system/runtime.config.ts} +1 -1
- package/config/system/server.config.ts +68 -0
- package/config/system/services.config.ts +46 -0
- package/config/{system.config.ts → system/system.config.ts} +1 -1
- package/core/build/flux-plugins-generator.ts +325 -325
- package/core/build/index.ts +39 -27
- package/core/build/live-components-generator.ts +3 -3
- package/core/build/optimizer.ts +235 -235
- package/core/cli/command-registry.ts +6 -4
- package/core/cli/commands/build.ts +79 -0
- package/core/cli/commands/create.ts +54 -0
- package/core/cli/commands/dev.ts +101 -0
- package/core/cli/commands/help.ts +34 -0
- package/core/cli/commands/index.ts +34 -0
- package/core/cli/commands/make-plugin.ts +90 -0
- package/core/cli/commands/plugin-add.ts +197 -0
- package/core/cli/commands/plugin-deps.ts +2 -2
- package/core/cli/commands/plugin-list.ts +208 -0
- package/core/cli/commands/plugin-remove.ts +170 -0
- package/core/cli/generators/component.ts +769 -769
- package/core/cli/generators/controller.ts +1 -1
- package/core/cli/generators/index.ts +146 -146
- package/core/cli/generators/interactive.ts +227 -227
- package/core/cli/generators/plugin.ts +2 -2
- package/core/cli/generators/prompts.ts +82 -82
- package/core/cli/generators/route.ts +6 -6
- package/core/cli/generators/service.ts +2 -2
- package/core/cli/generators/template-engine.ts +4 -3
- package/core/cli/generators/types.ts +2 -2
- package/core/cli/generators/utils.ts +191 -191
- package/core/cli/index.ts +115 -686
- package/core/cli/plugin-discovery.ts +2 -2
- package/core/client/LiveComponentsProvider.tsx +60 -8
- package/core/client/api/eden.ts +183 -0
- package/core/client/api/index.ts +11 -0
- package/core/client/components/Live.tsx +104 -0
- package/core/client/fluxstack.ts +1 -9
- package/core/client/hooks/AdaptiveChunkSizer.ts +215 -215
- package/core/client/hooks/state-validator.ts +1 -1
- package/core/client/hooks/useAuth.ts +48 -48
- package/core/client/hooks/useChunkedUpload.ts +85 -35
- package/core/client/hooks/useLiveChunkedUpload.ts +87 -0
- package/core/client/hooks/useLiveComponent.ts +800 -0
- package/core/client/hooks/useLiveUpload.ts +71 -0
- package/core/client/hooks/useRoom.ts +409 -0
- package/core/client/hooks/useRoomProxy.ts +382 -0
- package/core/client/index.ts +17 -68
- package/core/client/standalone-entry.ts +8 -0
- package/core/client/standalone.ts +74 -53
- package/core/client/state/createStore.ts +192 -192
- package/core/client/state/index.ts +14 -14
- package/core/config/index.ts +70 -291
- package/core/config/schema.ts +42 -723
- package/core/framework/client.ts +131 -131
- package/core/framework/index.ts +7 -7
- package/core/framework/server.ts +47 -40
- package/core/framework/types.ts +2 -2
- package/core/index.ts +23 -4
- package/core/live/ComponentRegistry.ts +3 -3
- package/core/live/types.ts +77 -0
- package/core/plugins/built-in/index.ts +134 -134
- package/core/plugins/built-in/live-components/commands/create-live-component.ts +242 -1066
- package/core/plugins/built-in/live-components/index.ts +1 -1
- package/core/plugins/built-in/monitoring/index.ts +111 -47
- package/core/plugins/built-in/static/index.ts +1 -1
- package/core/plugins/built-in/swagger/index.ts +68 -265
- package/core/plugins/built-in/vite/index.ts +85 -185
- package/core/plugins/built-in/vite/vite-dev.ts +10 -16
- package/core/plugins/config.ts +9 -7
- package/core/plugins/dependency-manager.ts +31 -1
- package/core/plugins/discovery.ts +19 -7
- package/core/plugins/executor.ts +2 -2
- package/core/plugins/index.ts +203 -203
- package/core/plugins/manager.ts +27 -39
- package/core/plugins/module-resolver.ts +19 -8
- package/core/plugins/registry.ts +255 -19
- package/core/plugins/types.ts +20 -53
- package/core/server/framework.ts +66 -43
- package/core/server/index.ts +15 -15
- package/core/server/live/ComponentRegistry.ts +78 -71
- package/core/server/live/FileUploadManager.ts +23 -10
- package/core/server/live/LiveComponentPerformanceMonitor.ts +1 -1
- package/core/server/live/LiveRoomManager.ts +261 -0
- package/core/server/live/RoomEventBus.ts +234 -0
- package/core/server/live/RoomStateManager.ts +172 -0
- package/core/server/live/StateSignature.ts +643 -643
- package/core/server/live/WebSocketConnectionManager.ts +30 -19
- package/core/server/live/auto-generated-components.ts +21 -9
- package/core/server/live/index.ts +14 -0
- package/core/server/live/websocket-plugin.ts +214 -67
- package/core/server/middleware/elysia-helpers.ts +7 -2
- package/core/server/middleware/errorHandling.ts +1 -1
- package/core/server/middleware/index.ts +31 -31
- package/core/server/plugins/database.ts +180 -180
- package/core/server/plugins/static-files-plugin.ts +69 -69
- package/core/server/plugins/swagger.ts +1 -1
- package/core/server/rooms/RoomBroadcaster.ts +357 -0
- package/core/server/rooms/RoomSystem.ts +463 -0
- package/core/server/rooms/index.ts +13 -0
- package/core/server/services/BaseService.ts +1 -1
- package/core/server/services/ServiceContainer.ts +1 -1
- package/core/server/services/index.ts +8 -8
- package/core/templates/create-project.ts +12 -12
- package/core/testing/index.ts +9 -9
- package/core/testing/setup.ts +73 -73
- package/core/types/api.ts +168 -168
- package/core/types/build.ts +219 -219
- package/core/types/config.ts +56 -26
- package/core/types/index.ts +4 -4
- package/core/types/plugin.ts +107 -107
- package/core/types/types.ts +353 -14
- package/core/utils/build-logger.ts +324 -324
- package/core/utils/config-schema.ts +480 -480
- package/core/utils/env.ts +2 -8
- package/core/utils/errors/codes.ts +114 -114
- package/core/utils/errors/handlers.ts +36 -1
- package/core/utils/errors/index.ts +49 -5
- package/core/utils/errors/middleware.ts +113 -113
- package/core/utils/helpers.ts +6 -16
- package/core/utils/index.ts +17 -17
- package/core/utils/logger/colors.ts +114 -114
- package/core/utils/logger/config.ts +13 -9
- package/core/utils/logger/formatter.ts +82 -82
- package/core/utils/logger/group-logger.ts +101 -101
- package/core/utils/logger/index.ts +6 -1
- package/core/utils/logger/stack-trace.ts +3 -1
- package/core/utils/logger/startup-banner.ts +82 -82
- package/core/utils/logger/winston-logger.ts +152 -152
- package/core/utils/monitoring/index.ts +211 -211
- package/core/utils/sync-version.ts +66 -66
- package/core/utils/version.ts +1 -1
- package/create-fluxstack.ts +8 -7
- package/package.json +12 -13
- package/plugins/crypto-auth/cli/make-protected-route.command.ts +1 -1
- package/plugins/crypto-auth/client/CryptoAuthClient.ts +302 -302
- package/plugins/crypto-auth/client/components/index.ts +11 -11
- package/plugins/crypto-auth/client/index.ts +11 -11
- package/plugins/crypto-auth/config/index.ts +1 -1
- package/plugins/crypto-auth/index.ts +4 -4
- package/plugins/crypto-auth/package.json +65 -65
- package/plugins/crypto-auth/server/AuthMiddleware.ts +1 -1
- package/plugins/crypto-auth/server/CryptoAuthService.ts +185 -185
- package/plugins/crypto-auth/server/index.ts +21 -21
- package/plugins/crypto-auth/server/middlewares/cryptoAuthAdmin.ts +3 -3
- package/plugins/crypto-auth/server/middlewares/cryptoAuthOptional.ts +1 -1
- package/plugins/crypto-auth/server/middlewares/cryptoAuthPermissions.ts +2 -2
- package/plugins/crypto-auth/server/middlewares/cryptoAuthRequired.ts +2 -2
- package/plugins/crypto-auth/server/middlewares/helpers.ts +1 -1
- package/plugins/crypto-auth/server/middlewares/index.ts +22 -22
- package/tsconfig.api-strict.json +16 -0
- package/tsconfig.json +48 -52
- package/{app/client/tsconfig.node.json → tsconfig.node.json} +25 -25
- package/types/global.d.ts +29 -29
- package/types/vitest.d.ts +8 -8
- package/vite.config.ts +38 -62
- package/vitest.config.live.ts +10 -9
- package/vitest.config.ts +29 -17
- package/app/client/README.md +0 -69
- package/app/client/SIMPLIFICATION.md +0 -140
- package/app/client/frontend-only.ts +0 -12
- package/app/client/src/live/FileUploadExample.tsx +0 -359
- package/app/client/src/live/MinimalLiveClock.tsx +0 -47
- package/app/client/src/live/QuickUploadTest.tsx +0 -193
- package/app/client/tsconfig.app.json +0 -45
- package/app/client/tsconfig.json +0 -7
- package/app/client/zustand-setup.md +0 -65
- package/app/server/backend-only.ts +0 -18
- package/app/server/live/LiveClockComponent.ts +0 -215
- package/app/server/live/LiveFileUploadComponent.ts +0 -77
- package/app/server/routes/env-test.ts +0 -110
- package/core/client/hooks/index.ts +0 -7
- package/core/client/hooks/useHybridLiveComponent.ts +0 -685
- package/core/client/hooks/useTypedLiveComponent.ts +0 -133
- package/core/client/hooks/useWebSocket.ts +0 -361
- package/core/config/env.ts +0 -546
- package/core/config/loader.ts +0 -522
- package/core/config/runtime-config.ts +0 -327
- package/core/config/validator.ts +0 -540
- package/core/server/backend-entry.ts +0 -51
- package/core/server/standalone.ts +0 -106
- package/core/utils/regenerate-files.ts +0 -69
- package/fluxstack.config.ts +0 -354
|
@@ -1,212 +1,212 @@
|
|
|
1
|
-
export interface Metric {
|
|
2
|
-
name: string
|
|
3
|
-
type: 'counter' | 'gauge' | 'histogram'
|
|
4
|
-
help: string
|
|
5
|
-
labels?: string[]
|
|
6
|
-
value?: number
|
|
7
|
-
values?: number[]
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface Counter extends Metric {
|
|
11
|
-
type: 'counter'
|
|
12
|
-
inc(value?: number, labels?: Record<string, string>): void
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface Gauge extends Metric {
|
|
16
|
-
type: 'gauge'
|
|
17
|
-
set(value: number, labels?: Record<string, string>): void
|
|
18
|
-
inc(value?: number, labels?: Record<string, string>): void
|
|
19
|
-
dec(value?: number, labels?: Record<string, string>): void
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface Histogram extends Metric {
|
|
23
|
-
type: 'histogram'
|
|
24
|
-
observe(value: number, labels?: Record<string, string>): void
|
|
25
|
-
buckets: number[]
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface SystemMetrics {
|
|
29
|
-
memoryUsage: {
|
|
30
|
-
rss: number
|
|
31
|
-
heapTotal: number
|
|
32
|
-
heapUsed: number
|
|
33
|
-
external: number
|
|
34
|
-
}
|
|
35
|
-
cpuUsage: {
|
|
36
|
-
user: number
|
|
37
|
-
system: number
|
|
38
|
-
}
|
|
39
|
-
eventLoopLag: number
|
|
40
|
-
uptime: number
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface HttpMetrics {
|
|
44
|
-
requestsTotal: number
|
|
45
|
-
requestDuration: number[]
|
|
46
|
-
requestSize: number[]
|
|
47
|
-
responseSize: number[]
|
|
48
|
-
errorRate: number
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export class MetricsCollector {
|
|
52
|
-
private metrics: Map<string, Metric> = new Map()
|
|
53
|
-
private httpMetrics: HttpMetrics = {
|
|
54
|
-
requestsTotal: 0,
|
|
55
|
-
requestDuration: [],
|
|
56
|
-
requestSize: [],
|
|
57
|
-
responseSize: [],
|
|
58
|
-
errorRate: 0
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Create metrics
|
|
62
|
-
createCounter(name: string, help: string, labels?: string[]): Counter {
|
|
63
|
-
const counter: Counter = {
|
|
64
|
-
name,
|
|
65
|
-
type: 'counter',
|
|
66
|
-
help,
|
|
67
|
-
labels,
|
|
68
|
-
value: 0,
|
|
69
|
-
inc: (value = 1, _labels) => {
|
|
70
|
-
counter.value = (counter.value || 0) + value
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
this.metrics.set(name, counter)
|
|
75
|
-
return counter
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
createGauge(name: string, help: string, labels?: string[]): Gauge {
|
|
79
|
-
const gauge: Gauge = {
|
|
80
|
-
name,
|
|
81
|
-
type: 'gauge',
|
|
82
|
-
help,
|
|
83
|
-
labels,
|
|
84
|
-
value: 0,
|
|
85
|
-
set: (value, _labels) => {
|
|
86
|
-
gauge.value = value
|
|
87
|
-
},
|
|
88
|
-
inc: (value = 1, _labels) => {
|
|
89
|
-
gauge.value = (gauge.value || 0) + value
|
|
90
|
-
},
|
|
91
|
-
dec: (value = 1, _labels) => {
|
|
92
|
-
gauge.value = (gauge.value || 0) - value
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
this.metrics.set(name, gauge)
|
|
97
|
-
return gauge
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
createHistogram(name: string, help: string, buckets: number[] = [0.1, 0.5, 1, 2.5, 5, 10]): Histogram {
|
|
101
|
-
const histogram: Histogram = {
|
|
102
|
-
name,
|
|
103
|
-
type: 'histogram',
|
|
104
|
-
help,
|
|
105
|
-
buckets,
|
|
106
|
-
values: [],
|
|
107
|
-
observe: (value, _labels) => {
|
|
108
|
-
histogram.values = histogram.values || []
|
|
109
|
-
histogram.values.push(value)
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
this.metrics.set(name, histogram)
|
|
114
|
-
return histogram
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// HTTP metrics
|
|
118
|
-
recordHttpRequest(_method: string, _path: string, statusCode: number, duration: number, requestSize?: number, responseSize?: number): void {
|
|
119
|
-
this.httpMetrics.requestsTotal++
|
|
120
|
-
this.httpMetrics.requestDuration.push(duration)
|
|
121
|
-
|
|
122
|
-
if (requestSize) {
|
|
123
|
-
this.httpMetrics.requestSize.push(requestSize)
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (responseSize) {
|
|
127
|
-
this.httpMetrics.responseSize.push(responseSize)
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (statusCode >= 400) {
|
|
131
|
-
this.httpMetrics.errorRate = this.calculateErrorRate()
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// System metrics
|
|
136
|
-
getSystemMetrics(): SystemMetrics {
|
|
137
|
-
const memUsage = process.memoryUsage()
|
|
138
|
-
const cpuUsage = process.cpuUsage()
|
|
139
|
-
|
|
140
|
-
return {
|
|
141
|
-
memoryUsage: {
|
|
142
|
-
rss: memUsage.rss,
|
|
143
|
-
heapTotal: memUsage.heapTotal,
|
|
144
|
-
heapUsed: memUsage.heapUsed,
|
|
145
|
-
external: memUsage.external
|
|
146
|
-
},
|
|
147
|
-
cpuUsage: {
|
|
148
|
-
user: cpuUsage.user,
|
|
149
|
-
system: cpuUsage.system
|
|
150
|
-
},
|
|
151
|
-
eventLoopLag: this.measureEventLoopLag(),
|
|
152
|
-
uptime: process.uptime()
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Get all metrics
|
|
157
|
-
getAllMetrics(): Map<string, Metric> {
|
|
158
|
-
return new Map(this.metrics)
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
getHttpMetrics(): HttpMetrics {
|
|
162
|
-
return { ...this.httpMetrics }
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Export metrics in Prometheus format
|
|
166
|
-
exportPrometheus(): string {
|
|
167
|
-
let output = ''
|
|
168
|
-
|
|
169
|
-
for (const metric of this.metrics.values()) {
|
|
170
|
-
output += `# HELP ${metric.name} ${metric.help}\n`
|
|
171
|
-
output += `# TYPE ${metric.name} ${metric.type}\n`
|
|
172
|
-
|
|
173
|
-
if (metric.type === 'counter' || metric.type === 'gauge') {
|
|
174
|
-
output += `${metric.name} ${metric.value || 0}\n`
|
|
175
|
-
} else if (metric.type === 'histogram' && metric.values) {
|
|
176
|
-
const values = metric.values.sort((a, b) => a - b)
|
|
177
|
-
const buckets = (metric as Histogram).buckets
|
|
178
|
-
|
|
179
|
-
for (const bucket of buckets) {
|
|
180
|
-
const count = values.filter(v => v <= bucket).length
|
|
181
|
-
output += `${metric.name}_bucket{le="${bucket}"} ${count}\n`
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
output += `${metric.name}_bucket{le="+Inf"} ${values.length}\n`
|
|
185
|
-
output += `${metric.name}_count ${values.length}\n`
|
|
186
|
-
output += `${metric.name}_sum ${values.reduce((sum, v) => sum + v, 0)}\n`
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
output += '\n'
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return output
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
private calculateErrorRate(): number {
|
|
196
|
-
const totalRequests = this.httpMetrics.requestsTotal
|
|
197
|
-
if (totalRequests === 0) return 0
|
|
198
|
-
|
|
199
|
-
// This is a simplified calculation - in a real implementation,
|
|
200
|
-
// you'd track error counts separately
|
|
201
|
-
return 0 // Placeholder
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
private measureEventLoopLag(): number {
|
|
205
|
-
const start = process.hrtime.bigint()
|
|
206
|
-
setImmediate(() => {
|
|
207
|
-
const lag = Number(process.hrtime.bigint() - start) / 1e6 // Convert to milliseconds
|
|
208
|
-
return lag
|
|
209
|
-
})
|
|
210
|
-
return 0 // Placeholder - actual implementation would be more complex
|
|
211
|
-
}
|
|
1
|
+
export interface Metric {
|
|
2
|
+
name: string
|
|
3
|
+
type: 'counter' | 'gauge' | 'histogram'
|
|
4
|
+
help: string
|
|
5
|
+
labels?: string[]
|
|
6
|
+
value?: number
|
|
7
|
+
values?: number[]
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface Counter extends Metric {
|
|
11
|
+
type: 'counter'
|
|
12
|
+
inc(value?: number, labels?: Record<string, string>): void
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface Gauge extends Metric {
|
|
16
|
+
type: 'gauge'
|
|
17
|
+
set(value: number, labels?: Record<string, string>): void
|
|
18
|
+
inc(value?: number, labels?: Record<string, string>): void
|
|
19
|
+
dec(value?: number, labels?: Record<string, string>): void
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface Histogram extends Metric {
|
|
23
|
+
type: 'histogram'
|
|
24
|
+
observe(value: number, labels?: Record<string, string>): void
|
|
25
|
+
buckets: number[]
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface SystemMetrics {
|
|
29
|
+
memoryUsage: {
|
|
30
|
+
rss: number
|
|
31
|
+
heapTotal: number
|
|
32
|
+
heapUsed: number
|
|
33
|
+
external: number
|
|
34
|
+
}
|
|
35
|
+
cpuUsage: {
|
|
36
|
+
user: number
|
|
37
|
+
system: number
|
|
38
|
+
}
|
|
39
|
+
eventLoopLag: number
|
|
40
|
+
uptime: number
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface HttpMetrics {
|
|
44
|
+
requestsTotal: number
|
|
45
|
+
requestDuration: number[]
|
|
46
|
+
requestSize: number[]
|
|
47
|
+
responseSize: number[]
|
|
48
|
+
errorRate: number
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export class MetricsCollector {
|
|
52
|
+
private metrics: Map<string, Metric> = new Map()
|
|
53
|
+
private httpMetrics: HttpMetrics = {
|
|
54
|
+
requestsTotal: 0,
|
|
55
|
+
requestDuration: [],
|
|
56
|
+
requestSize: [],
|
|
57
|
+
responseSize: [],
|
|
58
|
+
errorRate: 0
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Create metrics
|
|
62
|
+
createCounter(name: string, help: string, labels?: string[]): Counter {
|
|
63
|
+
const counter: Counter = {
|
|
64
|
+
name,
|
|
65
|
+
type: 'counter',
|
|
66
|
+
help,
|
|
67
|
+
labels,
|
|
68
|
+
value: 0,
|
|
69
|
+
inc: (value = 1, _labels) => {
|
|
70
|
+
counter.value = (counter.value || 0) + value
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
this.metrics.set(name, counter)
|
|
75
|
+
return counter
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
createGauge(name: string, help: string, labels?: string[]): Gauge {
|
|
79
|
+
const gauge: Gauge = {
|
|
80
|
+
name,
|
|
81
|
+
type: 'gauge',
|
|
82
|
+
help,
|
|
83
|
+
labels,
|
|
84
|
+
value: 0,
|
|
85
|
+
set: (value, _labels) => {
|
|
86
|
+
gauge.value = value
|
|
87
|
+
},
|
|
88
|
+
inc: (value = 1, _labels) => {
|
|
89
|
+
gauge.value = (gauge.value || 0) + value
|
|
90
|
+
},
|
|
91
|
+
dec: (value = 1, _labels) => {
|
|
92
|
+
gauge.value = (gauge.value || 0) - value
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
this.metrics.set(name, gauge)
|
|
97
|
+
return gauge
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
createHistogram(name: string, help: string, buckets: number[] = [0.1, 0.5, 1, 2.5, 5, 10]): Histogram {
|
|
101
|
+
const histogram: Histogram = {
|
|
102
|
+
name,
|
|
103
|
+
type: 'histogram',
|
|
104
|
+
help,
|
|
105
|
+
buckets,
|
|
106
|
+
values: [],
|
|
107
|
+
observe: (value, _labels) => {
|
|
108
|
+
histogram.values = histogram.values || []
|
|
109
|
+
histogram.values.push(value)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
this.metrics.set(name, histogram)
|
|
114
|
+
return histogram
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// HTTP metrics
|
|
118
|
+
recordHttpRequest(_method: string, _path: string, statusCode: number, duration: number, requestSize?: number, responseSize?: number): void {
|
|
119
|
+
this.httpMetrics.requestsTotal++
|
|
120
|
+
this.httpMetrics.requestDuration.push(duration)
|
|
121
|
+
|
|
122
|
+
if (requestSize) {
|
|
123
|
+
this.httpMetrics.requestSize.push(requestSize)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (responseSize) {
|
|
127
|
+
this.httpMetrics.responseSize.push(responseSize)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (statusCode >= 400) {
|
|
131
|
+
this.httpMetrics.errorRate = this.calculateErrorRate()
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// System metrics
|
|
136
|
+
getSystemMetrics(): SystemMetrics {
|
|
137
|
+
const memUsage = process.memoryUsage()
|
|
138
|
+
const cpuUsage = process.cpuUsage()
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
memoryUsage: {
|
|
142
|
+
rss: memUsage.rss,
|
|
143
|
+
heapTotal: memUsage.heapTotal,
|
|
144
|
+
heapUsed: memUsage.heapUsed,
|
|
145
|
+
external: memUsage.external
|
|
146
|
+
},
|
|
147
|
+
cpuUsage: {
|
|
148
|
+
user: cpuUsage.user,
|
|
149
|
+
system: cpuUsage.system
|
|
150
|
+
},
|
|
151
|
+
eventLoopLag: this.measureEventLoopLag(),
|
|
152
|
+
uptime: process.uptime()
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Get all metrics
|
|
157
|
+
getAllMetrics(): Map<string, Metric> {
|
|
158
|
+
return new Map(this.metrics)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
getHttpMetrics(): HttpMetrics {
|
|
162
|
+
return { ...this.httpMetrics }
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Export metrics in Prometheus format
|
|
166
|
+
exportPrometheus(): string {
|
|
167
|
+
let output = ''
|
|
168
|
+
|
|
169
|
+
for (const metric of this.metrics.values()) {
|
|
170
|
+
output += `# HELP ${metric.name} ${metric.help}\n`
|
|
171
|
+
output += `# TYPE ${metric.name} ${metric.type}\n`
|
|
172
|
+
|
|
173
|
+
if (metric.type === 'counter' || metric.type === 'gauge') {
|
|
174
|
+
output += `${metric.name} ${metric.value || 0}\n`
|
|
175
|
+
} else if (metric.type === 'histogram' && metric.values) {
|
|
176
|
+
const values = metric.values.sort((a, b) => a - b)
|
|
177
|
+
const buckets = (metric as Histogram).buckets
|
|
178
|
+
|
|
179
|
+
for (const bucket of buckets) {
|
|
180
|
+
const count = values.filter(v => v <= bucket).length
|
|
181
|
+
output += `${metric.name}_bucket{le="${bucket}"} ${count}\n`
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
output += `${metric.name}_bucket{le="+Inf"} ${values.length}\n`
|
|
185
|
+
output += `${metric.name}_count ${values.length}\n`
|
|
186
|
+
output += `${metric.name}_sum ${values.reduce((sum, v) => sum + v, 0)}\n`
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
output += '\n'
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return output
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
private calculateErrorRate(): number {
|
|
196
|
+
const totalRequests = this.httpMetrics.requestsTotal
|
|
197
|
+
if (totalRequests === 0) return 0
|
|
198
|
+
|
|
199
|
+
// This is a simplified calculation - in a real implementation,
|
|
200
|
+
// you'd track error counts separately
|
|
201
|
+
return 0 // Placeholder
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
private measureEventLoopLag(): number {
|
|
205
|
+
const start = process.hrtime.bigint()
|
|
206
|
+
setImmediate(() => {
|
|
207
|
+
const lag = Number(process.hrtime.bigint() - start) / 1e6 // Convert to milliseconds
|
|
208
|
+
return lag
|
|
209
|
+
})
|
|
210
|
+
return 0 // Placeholder - actual implementation would be more complex
|
|
211
|
+
}
|
|
212
212
|
}
|
|
@@ -1,67 +1,67 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Version Synchronization Utility
|
|
5
|
-
* Ensures version consistency between package.json and version.ts
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { readFileSync, writeFileSync } from 'fs'
|
|
9
|
-
import { join } from 'path'
|
|
10
|
-
|
|
11
|
-
interface PackageJson {
|
|
12
|
-
version: string
|
|
13
|
-
[key: string]: any
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Read version from package.json
|
|
18
|
-
*/
|
|
19
|
-
function getPackageVersion(): string {
|
|
20
|
-
const packagePath = join(process.cwd(), 'package.json')
|
|
21
|
-
const packageContent = readFileSync(packagePath, 'utf-8')
|
|
22
|
-
const packageJson: PackageJson = JSON.parse(packageContent)
|
|
23
|
-
return packageJson.version
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Update version.ts with the version from package.json
|
|
28
|
-
*/
|
|
29
|
-
function updateVersionFile(version: string, silent = false): void {
|
|
30
|
-
const versionPath = join(process.cwd(), 'core/utils/version.ts')
|
|
31
|
-
const versionContent = `/**
|
|
32
|
-
* FluxStack Framework Version
|
|
33
|
-
* Single source of truth for version number
|
|
34
|
-
* Auto-synced with package.json
|
|
35
|
-
*/
|
|
36
|
-
export const FLUXSTACK_VERSION = '${version}'
|
|
37
|
-
`
|
|
38
|
-
writeFileSync(versionPath, versionContent)
|
|
39
|
-
if (!silent) {
|
|
40
|
-
console.log(`✅ Updated version.ts to v${version}`)
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Main sync function
|
|
46
|
-
*/
|
|
47
|
-
function syncVersion(silent = false): void {
|
|
48
|
-
try {
|
|
49
|
-
const packageVersion = getPackageVersion()
|
|
50
|
-
updateVersionFile(packageVersion, silent)
|
|
51
|
-
if (!silent) {
|
|
52
|
-
console.log(`🔄 Version synchronized: v${packageVersion}`)
|
|
53
|
-
}
|
|
54
|
-
} catch (error) {
|
|
55
|
-
if (!silent) {
|
|
56
|
-
console.error('❌ Failed to sync version:', error)
|
|
57
|
-
}
|
|
58
|
-
process.exit(1)
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Run if called directly
|
|
63
|
-
if (import.meta.main) {
|
|
64
|
-
syncVersion()
|
|
65
|
-
}
|
|
66
|
-
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Version Synchronization Utility
|
|
5
|
+
* Ensures version consistency between package.json and version.ts
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { readFileSync, writeFileSync } from 'fs'
|
|
9
|
+
import { join } from 'path'
|
|
10
|
+
|
|
11
|
+
interface PackageJson {
|
|
12
|
+
version: string
|
|
13
|
+
[key: string]: any
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Read version from package.json
|
|
18
|
+
*/
|
|
19
|
+
function getPackageVersion(): string {
|
|
20
|
+
const packagePath = join(process.cwd(), 'package.json')
|
|
21
|
+
const packageContent = readFileSync(packagePath, 'utf-8')
|
|
22
|
+
const packageJson: PackageJson = JSON.parse(packageContent)
|
|
23
|
+
return packageJson.version
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Update version.ts with the version from package.json
|
|
28
|
+
*/
|
|
29
|
+
function updateVersionFile(version: string, silent = false): void {
|
|
30
|
+
const versionPath = join(process.cwd(), 'core/utils/version.ts')
|
|
31
|
+
const versionContent = `/**
|
|
32
|
+
* FluxStack Framework Version
|
|
33
|
+
* Single source of truth for version number
|
|
34
|
+
* Auto-synced with package.json
|
|
35
|
+
*/
|
|
36
|
+
export const FLUXSTACK_VERSION = '${version}'
|
|
37
|
+
`
|
|
38
|
+
writeFileSync(versionPath, versionContent)
|
|
39
|
+
if (!silent) {
|
|
40
|
+
console.log(`✅ Updated version.ts to v${version}`)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Main sync function
|
|
46
|
+
*/
|
|
47
|
+
function syncVersion(silent = false): void {
|
|
48
|
+
try {
|
|
49
|
+
const packageVersion = getPackageVersion()
|
|
50
|
+
updateVersionFile(packageVersion, silent)
|
|
51
|
+
if (!silent) {
|
|
52
|
+
console.log(`🔄 Version synchronized: v${packageVersion}`)
|
|
53
|
+
}
|
|
54
|
+
} catch (error) {
|
|
55
|
+
if (!silent) {
|
|
56
|
+
console.error('❌ Failed to sync version:', error)
|
|
57
|
+
}
|
|
58
|
+
process.exit(1)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Run if called directly
|
|
63
|
+
if (import.meta.main) {
|
|
64
|
+
syncVersion()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
67
|
export { syncVersion, getPackageVersion }
|
package/core/utils/version.ts
CHANGED
package/create-fluxstack.ts
CHANGED
|
@@ -91,8 +91,8 @@ program
|
|
|
91
91
|
'core',
|
|
92
92
|
'app',
|
|
93
93
|
'config', // ✅ CRITICAL: Copy config folder with declarative configs
|
|
94
|
-
'plugins',
|
|
95
|
-
'
|
|
94
|
+
'plugins', // TODO: Copy when crypto-auth plugin is complete
|
|
95
|
+
'LLMD', // ✅ CRITICAL: LLM-optimized documentation for AI assistants
|
|
96
96
|
'bun.lock', // ✅ CRITICAL: Copy lockfile to maintain working versions
|
|
97
97
|
'package.json', // ✅ Copy real package.json from framework
|
|
98
98
|
'tsconfig.json',
|
|
@@ -123,8 +123,8 @@ This folder is for your custom FluxStack plugins.
|
|
|
123
123
|
## 📖 Documentation
|
|
124
124
|
|
|
125
125
|
For complete plugin development guide, see:
|
|
126
|
-
- \`
|
|
127
|
-
- \`
|
|
126
|
+
- \`LLMD/resources/plugins-external.md\` - Full plugin documentation
|
|
127
|
+
- \`LLMD/reference/plugin-hooks.md\` - All available hooks
|
|
128
128
|
|
|
129
129
|
## 📦 Available CLI Commands
|
|
130
130
|
|
|
@@ -165,7 +165,7 @@ Plugins can intercept and modify requests using hooks:
|
|
|
165
165
|
|
|
166
166
|
\`\`\`typescript
|
|
167
167
|
// plugins/my-plugin/index.ts
|
|
168
|
-
import type { FluxStack, PluginContext, RequestContext, ResponseContext } from "
|
|
168
|
+
import type { FluxStack, PluginContext, RequestContext, ResponseContext } from "@core/plugins/types"
|
|
169
169
|
|
|
170
170
|
export class MyPlugin implements FluxStack.Plugin {
|
|
171
171
|
name = 'my-plugin'
|
|
@@ -418,7 +418,7 @@ FluxStack includes several built-in plugins that are ready to use:
|
|
|
418
418
|
|
|
419
419
|
\`\`\`typescript
|
|
420
420
|
// app/server/index.ts
|
|
421
|
-
import { loggerPlugin, swaggerPlugin, staticPlugin } from "
|
|
421
|
+
import { loggerPlugin, swaggerPlugin, staticPlugin } from "@core/server"
|
|
422
422
|
|
|
423
423
|
// Add built-in plugins
|
|
424
424
|
app.use(loggerPlugin)
|
|
@@ -458,7 +458,8 @@ app.use(authPlugin)
|
|
|
458
458
|
|
|
459
459
|
## 📖 Learn More
|
|
460
460
|
|
|
461
|
-
- **
|
|
461
|
+
- **LLM Documentation**: Check \`LLMD/INDEX.md\` for AI-optimized docs
|
|
462
|
+
- **Plugin Guide**: Check \`LLMD/resources/plugins-external.md\`
|
|
462
463
|
- **FluxStack Docs**: Visit the [FluxStack Repository](https://github.com/MarcosBrendonDePaula/FluxStack)
|
|
463
464
|
|
|
464
465
|
---
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-fluxstack",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.1",
|
|
4
4
|
"description": "⚡ Revolutionary full-stack TypeScript framework with Declarative Config System, Elysia + React + Bun",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"framework",
|
|
@@ -25,23 +25,21 @@
|
|
|
25
25
|
},
|
|
26
26
|
"scripts": {
|
|
27
27
|
"dev": "bun run core/cli/index.ts dev",
|
|
28
|
-
"dev:frontend": "bun run core/cli/index.ts frontend",
|
|
29
|
-
"dev:backend": "bun run core/cli/index.ts backend",
|
|
30
|
-
"sync-version": "bun run core/utils/sync-version.ts",
|
|
28
|
+
"dev:frontend": "bun run core/cli/index.ts dev --frontend-only",
|
|
29
|
+
"dev:backend": "bun run core/cli/index.ts dev --backend-only",
|
|
31
30
|
"build": "cross-env NODE_ENV=production bun run core/cli/index.ts build",
|
|
32
|
-
"build:frontend": "bun run core/cli/index.ts build
|
|
33
|
-
"build:backend": "bun run core/cli/index.ts build
|
|
31
|
+
"build:frontend": "cross-env NODE_ENV=production bun run core/cli/index.ts build --frontend-only",
|
|
32
|
+
"build:backend": "cross-env NODE_ENV=production bun run core/cli/index.ts build --backend-only",
|
|
34
33
|
"build:exe": "cross-env NODE_ENV=production && bun run core/cli/index.ts build && bun run core/cli/index.ts build:exe",
|
|
35
|
-
"start": "bun
|
|
36
|
-
"start:frontend": "bun run app/client/frontend-only.ts",
|
|
37
|
-
"start:backend": "bun run app/server/backend-only.ts",
|
|
34
|
+
"start": "NODE_ENV=production bun dist/index.js",
|
|
38
35
|
"create": "bun run core/cli/index.ts create",
|
|
39
36
|
"cli": "bun run core/cli/index.ts",
|
|
40
37
|
"make:component": "bun run core/cli/index.ts make:component",
|
|
41
|
-
"
|
|
38
|
+
"sync-version": "bun run core/utils/sync-version.ts",
|
|
42
39
|
"test": "vitest",
|
|
43
40
|
"test:ui": "vitest --ui",
|
|
44
|
-
"test:coverage": "vitest run --coverage"
|
|
41
|
+
"test:coverage": "vitest run --coverage",
|
|
42
|
+
"typecheck:api": "tsc --noEmit -p tsconfig.api-strict.json"
|
|
45
43
|
},
|
|
46
44
|
"devDependencies": {
|
|
47
45
|
"@eslint/js": "^9.30.1",
|
|
@@ -68,7 +66,8 @@
|
|
|
68
66
|
"tailwindcss": "^4.1.13",
|
|
69
67
|
"typescript": "^5.8.3",
|
|
70
68
|
"typescript-eslint": "^8.35.1",
|
|
71
|
-
"vite-plugin-
|
|
69
|
+
"vite-plugin-checker": "^0.12.0",
|
|
70
|
+
"vite-tsconfig-paths": "^6.0.5",
|
|
72
71
|
"vitest": "^3.2.4"
|
|
73
72
|
},
|
|
74
73
|
"dependencies": {
|
|
@@ -88,7 +87,7 @@
|
|
|
88
87
|
"react": "^19.1.0",
|
|
89
88
|
"react-dom": "^19.1.0",
|
|
90
89
|
"react-icons": "^5.5.0",
|
|
91
|
-
"react-router
|
|
90
|
+
"react-router": "^7.9.3",
|
|
92
91
|
"uuid": "^13.0.0",
|
|
93
92
|
"vite": "^7.1.7",
|
|
94
93
|
"winston": "^3.18.3",
|