@cruxjs/app 0.0.6 β†’ 0.0.7

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/README.md CHANGED
@@ -8,9 +8,10 @@
8
8
  </div>
9
9
 
10
10
  <div align="center">
11
- <img src="https://img.shields.io/badge/v-0.0.6-black"/>
12
- <img src="https://img.shields.io/badge/πŸ”₯-@cruxjs-black"/>
11
+ <img src="https://img.shields.io/badge/v-0.0.7-black"/>
12
+ <a href="https://github.com/cruxjs-org"><img src="https://img.shields.io/badge/πŸ”₯-@cruxjs-black"/></a>
13
13
  <br>
14
+ <img src="https://img.shields.io/badge/coverage-~%25-brightgreen" alt="Test Coverage" />
14
15
  <img src="https://img.shields.io/github/issues/cruxjs-org/app?style=flat" alt="Github Repo Issues" />
15
16
  <img src="https://img.shields.io/github/stars/cruxjs-org/app?style=social" alt="GitHub Repo stars" />
16
17
  </div>
@@ -22,602 +23,636 @@
22
23
 
23
24
  <!-- ╔══════════════════════════════ DOC ══════════════════════════════╗ -->
24
25
 
25
- - ## Quick Start πŸ”₯
26
-
27
- > **_CruxJS is a full-stack framework orchestrator built on [@minejs](https://github.com/minejs-org) that empowers developers to build modern web applications with **zero configuration**. It orchestrates without dictatingβ€”providing a plugin-based architecture where you control the flow._**
26
+ - ## Overview πŸ‘€
28
27
 
29
- - ### Setup
28
+ - #### Why ?
29
+ > To provide a unified full-stack framework that orchestrates server configuration, client builds, i18n, styling, SPA integration, and plugins in a single declarative configuration with zero boilerplate.
30
30
 
31
- > First, install [`hmm`](https://github.com/minejs-org/hmm) β€” the package manager for the CruxJS ecosystem.
31
+ - #### When ?
32
+ > When you need a production-ready full-stack application with:
33
+ > - Server configuration (port, logging, middleware)
34
+ > - Automatic client bundling with Bun
35
+ > - Style preprocessing (SCSS/Sass)
36
+ > - i18n setup and configuration
37
+ > - SPA plugin integration
38
+ > - Plugin system for extensibility
39
+ > - Unified lifecycle management
32
40
 
33
- ```bash
34
- # Install CruxJS App
35
- hmm i @cruxjs/app
41
+ > When you want to build modern full-stack SPAs without framework complexity.
36
42
 
37
- # Or install with plugins
38
- hmm i @cruxjs/app @cruxplug/spa
39
- ```
43
+ <br>
44
+ <br>
40
45
 
41
- - ### Basic Usage
46
+ - ## Quick Start πŸ”₯
42
47
 
43
- ```typescript
44
- import { createApp, type AppConfig } from '@cruxjs/app';
45
-
46
- const config: AppConfig = {
47
- debug: true,
48
-
49
- // Server configuration
50
- server: {
51
- port: 3000,
52
- host: 'localhost'
53
- },
54
-
55
- // Client build configuration (bundles with Bun)
56
- client: {
57
- entry: './src/client/browser.tsx',
58
- output: './src/shared/static/dist/js',
59
- minify: true,
60
- sourcemap: false
61
- },
62
-
63
- // UI library (installs from npm and exports min.css)
64
- ui: {
65
- package: '@mineui/core',
66
- output: './src/shared/static/dist/css'
67
- },
68
-
69
- // Custom styles (compiles SCSS/CSS)
70
- style: {
71
- entry: './src/client/ui/style/index.scss',
72
- output: './src/shared/static/dist/css/extra.css',
73
- minify: true,
74
- sourcemap: false
75
- },
76
-
77
- // Static files serving
78
- static: {
79
- path: '/static',
80
- directory: './src/shared/static',
81
- maxAge: 3600
82
- },
83
-
84
- // Plugins (SPA, API routes, databases, etc.)
85
- plugins: [/* your plugins */]
86
- };
48
+ > install [`hmm`](https://github.com/minejs-org/hmm) first.
87
49
 
88
- // Create and run the app
89
- const app = createApp(config);
90
- await app.start();
91
- ```
50
+ ```bash
51
+ # in your terminal
52
+ hmm i @cruxjs/app
53
+ ```
92
54
 
93
- <br>
55
+ <div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> </div>
94
56
 
95
- - ## Complete Example πŸ“–
57
+ - #### Setup
96
58
 
97
- ### Directory Structure
59
+ > Create your application configuration in a single file:
98
60
 
99
- ```
100
- src/
101
- β”œβ”€β”€ index.ts # Entry point (app config + setup)
102
- β”œβ”€β”€ client/
103
- β”‚ β”œβ”€β”€ browser.tsx # Client entry
104
- β”‚ └── ui/
105
- β”‚ β”œβ”€β”€ App.tsx
106
- β”‚ β”œβ”€β”€ pages/ # Page components
107
- β”‚ └── style/
108
- β”‚ └── index.scss # Custom styles
109
- β”œβ”€β”€ server/
110
- β”‚ β”œβ”€β”€ api/
111
- β”‚ β”‚ └── index.ts # API routes
112
- β”‚ └── schema.ts # Database schemas
113
- └── shared/
114
- └── static/ # Static assets (generated files here)
115
- ```
61
+ ```typescript
62
+ import { createApp, AppConfig } from '@cruxjs/app';
63
+ import { serverSPA } from '@cruxjs/spa';
64
+
65
+ const appConfig: AppConfig = {
66
+ debug : true,
67
+
68
+ // Server configuration
69
+ server: {
70
+ port : 3000,
71
+ host : 'localhost',
72
+ logging: {
73
+ level : 'info',
74
+ pretty : true
75
+ }
76
+ },
77
+
78
+ // Static files
79
+ static: {
80
+ path : '/static',
81
+ directory : './src/shared/static',
82
+ maxAge : 3600
83
+ },
84
+
85
+ // Client build configuration
86
+ client: {
87
+ entry : './src/app/client.ts',
88
+ output : './src/shared/static/dist/js',
89
+ minify : true,
90
+ sourcemap : false
91
+ },
92
+
93
+ // i18n configuration
94
+ i18n: {
95
+ defaultLanguage : 'en',
96
+ supportedLanguages : ['en', 'ar'],
97
+ basePath : './src/shared/static/dist/i18n'
98
+ },
99
+
100
+ // Style build configuration
101
+ style: {
102
+ entry : './src/app/ui/style/index.scss',
103
+ output : './src/shared/static/dist/css/min.css',
104
+ minify : true
105
+ },
106
+
107
+ plugins : []
108
+ };
116
109
 
117
- ### 1. Server Entry Point
118
-
119
- **src/index.ts**
120
- ```typescript
121
- import { createApp, type AppConfig } from '@cruxjs/app';
122
- import { serverSPA } from '@cruxplug/spa';
123
-
124
- const spaPlugin = serverSPA({
125
- baseUrl: 'http://localhost:3000',
126
- clientEntry: './src/client/browser.tsx',
127
- clientScriptPath: ['/static/dist/js/browser.js'],
128
- clientStylePath: ['/static/dist/css/min.css', '/static/dist/css/extra.css'],
129
-
130
- // SEO & E-E-A-T configuration
131
- author: 'Your Team',
132
- authorUrl: 'https://example.com/about',
133
- defaultDescription: 'Your app description',
134
- defaultKeywords: ['key', 'words'],
135
-
136
- enableAutoNotFound: true,
137
- pages: [
138
- {
139
- title: 'Home',
140
- path: '/',
141
- description: 'Welcome',
142
- keywords: ['home']
143
- }
144
- ],
145
- errorPages: [
146
- {
147
- statusCode: 404,
148
- title: '404 - Not Found',
149
- path: '/404'
150
- }
151
- ]
152
- });
153
-
154
- const config: AppConfig = {
155
- debug: true,
156
-
157
- server: {
158
- port: 3000,
159
- host: 'localhost',
160
- logging: { level: 'info', pretty: true }
161
- },
162
-
163
- // Build configuration
164
- client: {
165
- entry: './src/client/browser.tsx',
166
- output: './src/shared/static/dist/js',
167
- minify: true
168
- },
169
-
170
- ui: {
171
- package: '@mineui/core',
172
- output: './src/shared/static/dist/css'
173
- },
174
-
175
- style: {
176
- entry: './src/client/ui/style/index.scss',
177
- output: './src/shared/static/dist/css/extra.css',
178
- minify: true
179
- },
180
-
181
- static: {
182
- path: '/static',
183
- directory: './src/shared/static',
184
- maxAge: 3600
185
- },
186
-
187
- plugins: [spaPlugin]
188
- };
189
-
190
- const app = createApp(config);
191
- await app.start();
192
- ```
110
+ // Create and start app
111
+ const app = createApp(appConfig);
112
+ app.start();
113
+ ```
193
114
 
194
- ### 2. Client Entry Point
195
-
196
- **src/client/browser.tsx**
197
- ```typescript
198
- import { mount } from '@minejs/jsx';
199
- import { App } from './ui/App';
200
- import { ClientManager } from '@cruxjs/client';
201
- import { HomePage } from './ui/pages/HomePage';
202
- import { NotFoundPage } from './ui/pages/NotFoundPage';
203
-
204
- const clientManager = new ClientManager({
205
- debug: true,
206
- routes: {
207
- '/': HomePage,
208
- '/about': AboutPage,
209
- // ...more routes
210
- },
211
- notFoundComponent: NotFoundPage,
212
- errorComponent: ErrorPage
213
- });
214
-
215
- (async () => {
216
- await clientManager.boot();
217
- mount(<App />, '#app');
218
- await clientManager.ready('#app-main');
219
- })();
220
- ```
115
+ <div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> </div>
116
+ <br>
221
117
 
222
- ### 3. Define API Routes
118
+ - #### Usage
223
119
 
224
- **src/server/api/index.ts**
225
- ```typescript
226
- import type { RouteDefinition } from '@cruxjs/app';
120
+ > Add plugins and configure SPA:
227
121
 
228
- export const routes: RouteDefinition[] = [
229
- {
230
- method: 'GET',
231
- path: '/api/users',
232
- handler: async (ctx) => {
233
- return ctx.json({ users: [] });
234
- }
235
- },
236
- {
237
- method: 'POST',
238
- path: '/api/users',
239
- handler: async (ctx) => {
240
- const data = await ctx.request.json();
241
- return ctx.json({ created: true }, { status: 201 });
242
- }
243
- }
244
- ];
245
- ```
122
+ ```typescript
123
+ // Create SPA plugin
124
+ const spaPlugin = serverSPA({
125
+ baseUrl : 'http://localhost:3000',
126
+ clientEntry : './src/app/client.ts',
127
+ clientScriptPath : ['/static/dist/js/client.js'],
128
+ clientStylePath : ['/static/dist/css/min.css'],
129
+
130
+ pages: [
131
+ {
132
+ title : 'Home',
133
+ path : '/',
134
+ description : 'Welcome to our app'
135
+ }
136
+ ],
137
+
138
+ autoBootstrapClient : true
139
+ }, appConfig);
140
+
141
+ // Add plugin to app
142
+ appConfig.plugins.push(spaPlugin);
143
+
144
+ // Start app
145
+ const app = createApp(appConfig);
146
+ app.start();
147
+ ```
246
148
 
247
- ### 4. Add Custom Styles
149
+ <div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> </div>
150
+
151
+ - #### Server Configuration
152
+
153
+ ```typescript
154
+ server: {
155
+ // Port and host
156
+ port : 3000,
157
+ host : 'localhost',
158
+
159
+ // Logging configuration
160
+ logging: {
161
+ level : 'info', // 'debug' | 'info' | 'warn' | 'error'
162
+ pretty : true // Pretty-print logs
163
+ },
164
+
165
+ // CORS configuration (optional)
166
+ cors: {
167
+ origin : 'http://localhost:3000',
168
+ credentials : true
169
+ },
170
+
171
+ // Middleware (optional)
172
+ middleware: [
173
+ // Add custom middleware here
174
+ ]
175
+ }
176
+ ```
177
+
178
+ - #### Client Build Configuration
179
+
180
+ ```typescript
181
+ client: {
182
+ // Entry file for client bundle
183
+ entry : './src/app/client.ts',
184
+
185
+ // Output directory
186
+ output : './src/shared/static/dist/js',
187
+
188
+ // Build options
189
+ minify : true, // Minify bundle
190
+ sourcemap : false, // Generate source maps
191
+ target : 'browser', // Build target (browser, node, etc.)
192
+ external : [], // External dependencies
193
+
194
+ // Custom build configuration
195
+ define: {
196
+ 'process.env.VERSION': '"1.0.0"'
197
+ }
198
+ }
199
+ ```
200
+
201
+ - #### i18n Configuration
202
+
203
+ ```typescript
204
+ i18n: {
205
+ // Default language
206
+ defaultLanguage : 'en',
207
+
208
+ // Supported languages
209
+ supportedLanguages : ['en', 'ar', 'fr', 'de'],
210
+
211
+ // Base path for translation files
212
+ basePath : './src/shared/static/dist/i18n',
213
+
214
+ // Custom storage (optional)
215
+ storage : 'localStorage'
216
+ }
217
+ ```
218
+
219
+ - #### Style Build Configuration
220
+
221
+ ```typescript
222
+ style: {
223
+ // Entry SCSS/Sass file
224
+ entry : './src/app/ui/style/index.scss',
225
+
226
+ // Output CSS file
227
+ output : './src/shared/static/dist/css/min.css',
228
+
229
+ // Build options
230
+ minify : true, // Minify CSS
231
+ sourcemap : false, // Generate source maps
232
+
233
+ // Include paths
234
+ includePaths: [
235
+ './src/app/ui/components'
236
+ ]
237
+ }
238
+ ```
239
+
240
+ - #### Middleware
241
+
242
+ ```typescript
243
+ // Add custom middleware for request/response handling
244
+ server: {
245
+ middleware: [
246
+ {
247
+ path : '/api/*',
248
+ handler : async (req, res) => {
249
+ // Custom API handling
250
+ }
251
+ }
252
+ ]
253
+ }
254
+ ```
255
+
256
+ - #### Plugins
257
+
258
+ ```typescript
259
+ // Create custom plugins
260
+ const myPlugin = {
261
+ name : 'my-plugin',
262
+ version : '1.0.0',
263
+
264
+ onRegister : async (app) => {
265
+ console.log('Plugin registered');
266
+ },
267
+
268
+ onAwake : async (ctx) => {
269
+ console.log('Plugin awake');
270
+ },
271
+
272
+ onStart : async (ctx) => {
273
+ console.log('Plugin starting');
274
+ },
275
+
276
+ onReady : async (ctx) => {
277
+ console.log('Plugin ready');
278
+ }
279
+ };
280
+
281
+ appConfig.plugins.push(myPlugin);
282
+ ```
248
283
 
249
- **src/client/ui/style/index.scss**
250
- ```scss
251
- // Import UI library variables (if available)
252
- @import '@mineui/core/scss/variables';
284
+ <br>
285
+ <br>
253
286
 
254
- // Custom styles
255
- body {
256
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
257
- margin: 0;
258
- padding: 0;
259
- }
287
+ - ## Complete Example πŸ“‘
260
288
 
261
- .app {
262
- display: flex;
263
- flex-direction: column;
264
- min-height: 100vh;
265
- }
289
+ - ### src/index.ts
266
290
 
267
- // More custom styles...
268
- ```
291
+ ```typescript
292
+ import { createApp, AppConfig } from '@cruxjs/app';
293
+ import { serverSPA } from '@cruxjs/spa';
294
+
295
+ import * as HomePage from './app/ui/pages/home';
296
+ import * as ErrorPage from './app/ui/pages/error';
297
+
298
+ const appConfig: AppConfig = {
299
+ debug: true,
300
+
301
+ server: {
302
+ port : 3000,
303
+ host : 'localhost',
304
+ logging: {
305
+ level : 'info',
306
+ pretty : true
307
+ }
308
+ },
309
+
310
+ static: {
311
+ path : '/static',
312
+ directory : './src/shared/static',
313
+ maxAge : 3600,
314
+ index : ['index.html']
315
+ },
316
+
317
+ client: {
318
+ entry : './src/app/client.ts',
319
+ output : './src/shared/static/dist/js',
320
+ minify : true,
321
+ sourcemap : false,
322
+ },
323
+
324
+ i18n: {
325
+ defaultLanguage : 'en',
326
+ supportedLanguages : ['en', 'ar'],
327
+ basePath : './src/shared/static/dist/i18n'
328
+ },
329
+
330
+ style: {
331
+ entry : './src/app/ui/style/index.scss',
332
+ output : './src/shared/static/dist/css/min.css',
333
+ minify : true,
334
+ sourcemap : false,
335
+ },
336
+
337
+ plugins : []
338
+ };
269
339
 
270
- - ## How It Works πŸ—οΈ
340
+ const spaPlugin = serverSPA({
341
+ baseUrl : 'http://localhost:3000',
342
+ clientEntry : './src/app/client.ts',
343
+ clientScriptPath : ['/static/dist/js/client.js'],
344
+ clientStylePath : ['/static/dist/css/min.css'],
271
345
 
272
- CruxJS orchestrates your full-stack application through **4 lifecycle phases**:
346
+ author : 'Your Name',
347
+ authorUrl : 'https://github.com/yourname',
348
+ defaultDescription : 'My CruxJS Application',
349
+ defaultKeywords : ['cruxjs', 'framework', 'spa'],
273
350
 
274
- - #### **Phase 0: REGISTER**
275
- Plugins register and declare their capabilities (routes, schemas, middleware).
351
+ pages : [HomePage.meta],
352
+ errorPages : [ErrorPage.meta],
353
+ enableAutoNotFound : true,
354
+ autoBootstrapClient : true
355
+ }, appConfig);
276
356
 
277
- - #### **Phase 1: AWAKE**
278
- - Client is built using Bun's bundler
279
- - UI library (e.g., @mineui/core) is installed and CSS is extracted
280
- - Custom SCSS/CSS is compiled using Dart Sass
281
- - Databases are initialized with plugin schemas
282
- - i18n is set up
357
+ appConfig.plugins.push(spaPlugin);
283
358
 
284
- **Output structure:**
285
- ```
286
- src/shared/static/dist/
287
- β”œβ”€β”€ js/
288
- β”‚ └── browser.js (bundled client)
289
- └── css/
290
- β”œβ”€β”€ min.css (UI library CSS)
291
- └── extra.css (compiled custom styles)
359
+ const app = createApp(appConfig);
360
+ app.start();
292
361
  ```
293
362
 
294
- - #### **Phase 2: START**
295
- - Server is created with @minejs/server
296
- - Routes are merged (user routes + plugin routes)
297
- - Middleware stack is built
298
- - Static files handler is configured
363
+ - ### Directory Structure
299
364
 
300
- - #### **Phase 3: READY**
301
- - Server is listening and ready to handle requests
302
- - Plugins are fully operational
365
+ ```
366
+ src/
367
+ β”œβ”€β”€ index.ts # Main app config & entry
368
+ β”œβ”€β”€ app/
369
+ β”‚ β”œβ”€β”€ client.ts # Client config
370
+ β”‚ └── ui/
371
+ β”‚ β”œβ”€β”€ pages/
372
+ β”‚ β”‚ β”œβ”€β”€ home.tsx # Home page component
373
+ β”‚ β”‚ └── error.tsx # Error page component
374
+ β”‚ └── style/
375
+ β”‚ └── index.scss # Global styles
376
+ └── shared/
377
+ └── static/
378
+ β”œβ”€β”€ img/
379
+ β”‚ └── logo.png
380
+ └── dist/
381
+ β”œβ”€β”€ js/ # Client bundle output
382
+ β”œβ”€β”€ css/ # Style output
383
+ └── i18n/ # Translations
384
+ ```
303
385
 
304
386
  <br>
387
+ <br>
388
+
389
+ - ## Lifecycle Hooks πŸ”„
305
390
 
306
- - ## Building Your App πŸ› οΈ
307
-
308
- ### Client Build (JavaScript)
309
- ```typescript
310
- client: {
311
- entry: './src/client/browser.tsx',
312
- output: './src/shared/static/dist/js',
313
- target: 'browser', // or 'bun'
314
- minify: true, // Minify in production
315
- sourcemap: false, // Source maps in development
316
- external: [] // Dependencies to exclude
317
- }
318
- ```
319
- Uses Bun's bundler to create optimized JavaScript bundles.
320
-
321
- ### UI Library Build (CSS from npm)
322
- ```typescript
323
- ui: {
324
- package: '@mineui/core', // Any npm package
325
- output: './src/shared/static/dist/css'
326
- }
327
- ```
328
- - Installs the UI package from npm
329
- - Extracts `dist/mineui.css` and copies it as `min.css`
330
- - Perfect for pre-built component libraries
331
-
332
- ### Styles Build (SCSS to CSS)
333
- ```typescript
334
- style: {
335
- entry: './src/client/ui/style/index.scss',
336
- output: './src/shared/static/dist/css/extra.css',
337
- minify: true,
338
- sourcemap: false
339
- }
340
391
  ```
341
- - Compiles SCSS/CSS using Dart Sass (pure CSS output)
342
- - Minifies output in production
343
- - No JavaScript wrappersβ€”just clean CSS files
344
-
345
- ### All Together
346
- The SPA plugin links everything:
347
- ```typescript
348
- import { serverSPA } from '@cruxplug/spa';
349
-
350
- const spaPlugin = serverSPA({
351
- baseUrl: 'http://localhost:3000',
352
- clientEntry: './src/client/browser.tsx',
353
- clientScriptPath: ['/static/dist/js/browser.js'],
354
- clientStylePath: [
355
- '/static/dist/css/min.css', // UI library
356
- '/static/dist/css/extra.css' // Custom styles
357
- ],
358
- // ...SEO/E-E-A-T configuration
359
- });
392
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
393
+ β”‚ β”‚
394
+ β”‚ createApp(config) β”‚
395
+ β”‚ β”‚
396
+ β”œβ”€ INITIALIZE Phase β”‚
397
+ β”‚ β”œβ”€ Load configuration β”‚
398
+ β”‚ β”œβ”€ Initialize plugins β”‚
399
+ β”‚ └─ Setup server β”‚
400
+ β”‚ β”‚
401
+ β”œβ”€ BUILD Phase (in background) β”‚
402
+ β”‚ β”œβ”€ Build client bundle (Bun) β”‚
403
+ β”‚ β”œβ”€ Build styles (Sass) β”‚
404
+ β”‚ β”œβ”€ Setup i18n system β”‚
405
+ β”‚ └─ Run plugin onRegister hooks β”‚
406
+ β”‚ β”‚
407
+ β”œβ”€ AWAKE Phase β”‚
408
+ β”‚ β”œβ”€ Register routes β”‚
409
+ β”‚ β”œβ”€ Run plugin onAwake hooks β”‚
410
+ β”‚ └─ Verify configuration β”‚
411
+ β”‚ β”‚
412
+ β”œβ”€ START Phase β”‚
413
+ β”‚ β”œβ”€ Start HTTP server β”‚
414
+ β”‚ β”œβ”€ Run plugin onStart hooks β”‚
415
+ β”‚ └─ Listen on configured port β”‚
416
+ β”‚ β”‚
417
+ └─ READY Phase β”‚
418
+ β”œβ”€ Run plugin onReady hooks β”‚
419
+ β”œβ”€ Server accepting requests β”‚
420
+ └─ SPA fully operational β”‚
360
421
  ```
361
422
 
362
423
  <br>
424
+ <br>
363
425
 
364
- - ## Lifecycle Hooks πŸ”„
426
+ - ## API Reference πŸ“š
365
427
 
366
- Control your application at each phase:
367
-
368
- ```typescript
369
- createApp(config, {
370
- onAwake: async (ctx) => {
371
- // Databases ready, client built, plugins initialized
372
- // Perfect for: seed data, cache warming
373
- const db = ctx.databases.get('default');
374
- await db.query('INSERT INTO ...');
375
- },
376
-
377
- onStart: async (ctx) => {
378
- // Server created, routes merged, middleware ready
379
- // Perfect for: logging setup, route inspection
380
- console.log(`${ctx.routes.length} routes registered`);
381
- },
382
-
383
- onReady: async (ctx) => {
384
- // Server listening and ready
385
- // Perfect for: external service notifications
386
- const url = `http://${ctx.config.server.host}:${ctx.config.server.port}`;
387
- console.log(`πŸš€ Live at ${url}`);
388
- },
389
-
390
- onFinish: async (ctx) => {
391
- // Graceful shutdown
392
- // Perfect for: cleanup, connection closing
393
- },
394
-
395
- onError: async (ctx, phase, error) => {
396
- // Error handling across all phases
397
- console.error(`Error in ${phase}:`, error);
398
- }
399
- });
400
- ```
428
+ - ### AppConfig
401
429
 
402
- <br>
430
+ ```typescript
431
+ interface AppConfig {
432
+ // Debug mode
433
+ debug? : boolean;
434
+
435
+ // Server configuration (REQUIRED)
436
+ server: {
437
+ port : number;
438
+ host : string;
439
+ logging?: {
440
+ level : 'debug' | 'info' | 'warn' | 'error';
441
+ pretty? : boolean;
442
+ };
443
+ cors? : CorsConfig;
444
+ middleware? : Middleware[];
445
+ };
446
+
447
+ // Static files serving
448
+ static?: {
449
+ path : string; // URL path for static files
450
+ directory : string; // File system directory
451
+ maxAge? : number; // Cache duration (seconds)
452
+ index? : string[]; // Index files to serve
453
+ };
454
+
455
+ // Client build configuration
456
+ client?: {
457
+ entry : string;
458
+ output : string;
459
+ minify? : boolean;
460
+ sourcemap? : boolean;
461
+ target? : string;
462
+ external? : string[];
463
+ define? : Record<string, any>;
464
+ };
465
+
466
+ // i18n configuration
467
+ i18n? : I18nConfig;
468
+
469
+ // Style build configuration
470
+ style?: {
471
+ entry : string;
472
+ output : string;
473
+ minify? : boolean;
474
+ sourcemap? : boolean;
475
+ includePaths? : string[];
476
+ };
477
+
478
+ // Plugins
479
+ plugins? : CruxPlugin[];
480
+
481
+ // UI library configuration (optional)
482
+ ui?: {
483
+ package : string; // e.g., '@mineui/core'
484
+ output : string; // Output directory
485
+ };
486
+
487
+ // Database configuration (optional)
488
+ db? : DatabaseConfig;
489
+ }
490
+ ```
403
491
 
404
- - ## Plugins πŸ”Œ
492
+ <div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> </div>
405
493
 
406
- Extend CruxJS with plugins. They integrate seamlessly into the lifecycle:
494
+ - ### Application Instance
407
495
 
408
- ```typescript
409
- import type { CruxPlugin } from '@cruxjs/base';
496
+ ```typescript
497
+ const app = createApp(config);
410
498
 
411
- const myPlugin: CruxPlugin = {
412
- name: 'my-plugin',
413
- version: '1.0.0',
499
+ // Start the application
500
+ app.start();
414
501
 
415
- // Provide routes
416
- routes: [
417
- {
418
- method: 'GET',
419
- path: '/plugin/status',
420
- handler: async (ctx) => ctx.json({ status: 'ok' })
421
- }
422
- ],
423
-
424
- // Define database schemas
425
- schemas: [
426
- {
427
- name: 'my_table',
428
- columns: [
429
- { name: 'id', type: 'INTEGER PRIMARY KEY' },
430
- { name: 'data', type: 'TEXT' }
431
- ]
432
- }
433
- ],
434
-
435
- // Register middleware
436
- middleware: {
437
- 'my-middleware': async (ctx, next) => {
438
- console.log('Before request');
439
- const result = await next();
440
- console.log('After request');
441
- return result;
442
- }
443
- },
444
-
445
- // Hook into lifecycle
446
- hooks: {
447
- onAwake: async (ctx) => console.log('Plugin awake'),
448
- onStart: async (ctx) => console.log('Plugin start'),
449
- onReady: async (ctx) => console.log('Plugin ready'),
450
- onShutdown: async (ctx) => console.log('Plugin shutdown')
451
- }
452
- };
453
-
454
- // Use in config
455
- const config: AppConfig = {
456
- plugins: [myPlugin]
457
- };
458
- ```
502
+ // Get configuration
503
+ app.getConfig();
459
504
 
460
- **Popular Plugins:**
461
- - [@cruxplug/spa](https://github.com/cruxplug-org/spa) β€” Single Page Application with SEO/E-E-A-T
462
- - More coming soon...
505
+ // Register a plugin
506
+ app.use(plugin);
463
507
 
464
- <br>
508
+ // Get a plugin instance
509
+ app.getPlugin('plugin-name');
465
510
 
466
- - ## Database Support πŸ“Š
467
-
468
- Configure one or multiple databases:
469
-
470
- ```typescript
471
- const config: AppConfig = {
472
- database: [
473
- {
474
- name: 'primary',
475
- connection: './data/primary.db',
476
- schema: './src/schemas/primary.ts'
477
- },
478
- {
479
- name: 'cache',
480
- connection: './data/cache.db',
481
- schema: './src/schemas/cache.ts'
482
- }
483
- ]
484
- };
511
+ // Access logger
512
+ app.logger.info('Message');
485
513
 
486
- // Access in lifecycle hooks or plugins
487
- const app = createApp(config);
488
- const primaryDb = app.getContext().databases.get('primary');
489
- const cacheDb = app.getContext().databases.get('cache');
490
- ```
514
+ // Access database (if configured)
515
+ app.db?.query('SELECT * FROM users');
516
+
517
+ // Access plugin registry
518
+ app.plugins.getAll();
519
+ ```
520
+
521
+ - ### Plugin Interface
522
+
523
+ ```typescript
524
+ interface CruxPlugin {
525
+ name : string;
526
+ version : string;
527
+ routes? : RouteDefinition[];
528
+ middleware? : AppMiddleware[];
529
+
530
+ onRegister? : (app: AppInstance) => Promise<void>;
531
+ onAwake? : (ctx: LifecycleContext) => Promise<void>;
532
+ onStart? : (ctx: LifecycleContext) => Promise<void>;
533
+ onReady? : (ctx: LifecycleContext) => Promise<void>;
534
+ onShutdown? : (ctx: LifecycleContext) => Promise<void>;
535
+ }
536
+ ```
491
537
 
492
538
  <br>
539
+ <br>
493
540
 
494
- - ## Internationalization (i18n) 🌍
541
+ - ## Best Practices ✨
495
542
 
496
- Built-in multi-language support:
543
+ - #### Configuration Structure
497
544
 
498
- ```typescript
499
- const config: AppConfig = {
500
- i18n: {
501
- defaultLanguage: 'en',
502
- supportedLanguages: ['en', 'ar', 'fr', 'es'],
503
- basePath: './src/shared/static/i18n',
504
- fileExtension: 'json'
505
- }
506
- };
507
- ```
545
+ ```typescript
546
+ // βœ… DO: Keep configuration centralized
547
+ const appConfig: AppConfig = {
548
+ debug : process.env.DEBUG === 'true',
549
+ server : { port: parseInt(process.env.PORT || '3000') },
550
+ // ... rest of config
551
+ };
508
552
 
509
- **Directory structure:**
510
- ```
511
- src/shared/static/i18n/
512
- β”œβ”€β”€ en.json
513
- β”œβ”€β”€ ar.json
514
- β”œβ”€β”€ fr.json
515
- └── es.json
516
- ```
553
+ // ❌ DON'T: Scatter configuration
554
+ const app = createApp({});
555
+ app.config.server.port = 3000;
556
+ app.config.client.entry = './src/app/client.ts';
557
+ ```
517
558
 
518
- <br>
559
+ - #### Plugin Usage
519
560
 
520
- - ## Configuration πŸ”₯
561
+ ```typescript
562
+ // βœ… DO: Define plugins before creating app
563
+ const plugins = [
564
+ spaPlugin,
565
+ authPlugin,
566
+ analyticsPlugin
567
+ ];
568
+
569
+ const app = createApp({
570
+ plugins,
571
+ // ... rest of config
572
+ });
573
+
574
+ // ❌ DON'T: Add plugins after app creation
575
+ app.use(plugin);
576
+ ```
521
577
 
522
- ### AppConfig Interface
578
+ - #### Static Files
523
579
 
524
- ```typescript
525
- interface AppConfig {
526
- // Enable debug mode (affects minification, sourcemaps)
527
- debug?: boolean;
580
+ ```typescript
581
+ // βœ… DO: Use static configuration
582
+ static: {
583
+ path : '/static',
584
+ directory : './src/shared/static',
585
+ maxAge : 3600
586
+ }
528
587
 
529
- // Server configuration
530
- server?: {
531
- port?: number; // Default: 3000
532
- host?: string; // Default: 'localhost'
533
- logging?: {
534
- level?: 'debug' | 'info' | 'warn' | 'error';
535
- pretty?: boolean;
536
- };
537
- };
538
-
539
- // Client build (Bun bundler)
540
- client?: {
541
- entry: string; // Entry point (e.g., './src/client/browser.tsx')
542
- output: string; // Output directory
543
- target?: 'browser' | 'bun';
544
- minify?: boolean; // Default: !debug
545
- sourcemap?: boolean; // Default: debug
546
- external?: string[]; // Don't bundle these
547
- };
548
-
549
- // UI Library (npm package)
550
- ui?: {
551
- package: string; // Package name (e.g., '@mineui/core')
552
- output: string; // CSS output directory
553
- };
554
-
555
- // Custom styles (SCSS/CSS)
556
- style?: {
557
- entry: string; // Entry SCSS/CSS file
558
- output: string; // CSS output file (e.g., 'extra.css')
559
- minify?: boolean; // Default: !debug
560
- sourcemap?: boolean; // Default: debug
561
- };
562
-
563
- // Static files
564
- static?: {
565
- path: string; // Web path (e.g., '/static')
566
- directory: string; // Disk directory
567
- maxAge?: number; // Cache duration in seconds
568
- index?: string[]; // Default files
569
- };
570
-
571
- // Database configuration
572
- database?: DatabaseConfig | DatabaseConfig[];
573
-
574
- // Internationalization
575
- i18n?: {
576
- defaultLanguage: string;
577
- supportedLanguages: string[];
578
- basePath?: string;
579
- fileExtension?: string; // Default: 'json'
580
- };
581
-
582
- // Inline routes
583
- routes?: RouteDefinition[];
584
-
585
- // Plugins
586
- plugins?: CruxPlugin[];
587
-
588
- // Custom middleware
589
- middlewares?: Record<string, AppMiddleware>;
590
- }
591
- ```
588
+ // ❌ DON'T: Manual middleware setup
589
+ app.use(express.static('./src/shared/static'));
590
+ ```
592
591
 
593
- <br>
592
+ - #### Build Configuration
593
+
594
+ ```typescript
595
+ // βœ… DO: Configure builds in appConfig
596
+ client: {
597
+ entry : './src/app/client.ts',
598
+ output : './dist/js',
599
+ minify : !config.debug
600
+ }
594
601
 
602
+ // ❌ DON'T: Rely on external build tools
603
+ // Use webpack/vite separately
604
+ ```
605
+
606
+ - #### Error Handling
607
+
608
+ ```typescript
609
+ // βœ… DO: Define error pages via SPA plugin
610
+ const spaPlugin = serverSPA({
611
+ errorPages: [
612
+ {
613
+ statusCode : 404,
614
+ title : 'Not Found',
615
+ path : '/*'
616
+ }
617
+ ]
618
+ });
619
+
620
+ // ❌ DON'T: Manual error handlers
621
+ app.get('*', (req, res) => {
622
+ res.status(404).send('Not found');
623
+ });
624
+ ```
625
+
626
+ <br>
595
627
  <br>
596
628
 
597
- - ## API Reference πŸ”₯
629
+ - ## Integration with Other CruxJS Libraries πŸ”—
598
630
 
599
- ### Core Function
631
+ > @cruxjs/app integrates seamlessly with:
600
632
 
601
- ```typescript
602
- import { createApp, type AppConfig } from '@cruxjs/app';
633
+ - **[@cruxjs/spa](https://github.com/cruxjs-org/spa)**
634
+ > SPA plugin for server-side rendering and routing
603
635
 
604
- const app = createApp(config, {
605
- onAwake: async (ctx) => { /* ... */ },
606
- onStart: async (ctx) => { /* ... */ },
607
- onReady: async (ctx) => { /* ... */ },
608
- onFinish: async (ctx) => { /* ... */ },
609
- onError: async (ctx, phase, error) => { /* ... */ }
610
- });
636
+ - **[@cruxjs/client](https://github.com/cruxjs-org/client)**
637
+ > Client-side application manager with routing and lifecycle
611
638
 
612
- await app.start();
613
- ```
639
+ - **[@cruxjs/base](https://github.com/cruxjs-org/base)**
640
+ > Base types and plugin system
641
+
642
+ - **[@minejs/i18n](https://github.com/minejs-org/i18n)**
643
+ > i18n system (automatic setup)
644
+
645
+ - **[@minejs/server](https://github.com/minejs-org/server)**
646
+ > HTTP server (automatic setup)
614
647
 
615
- ### AppInstance Methods
648
+ - **[@minejs/browser](https://github.com/minejs-org/browser)**
649
+ > Browser utilities
616
650
 
617
- - `app.start()` β€” Start through all lifecycle phases
618
- - `app.stop()` β€” Stop server and cleanup
619
- - `app.restart()` β€” Restart the application
620
- - `app.getContext()` β€” Get current lifecycle context
651
+ - **Bun**
652
+ > Client bundler (automatic client builds)
653
+
654
+ - **Sass**
655
+ >Style preprocessing (automatic style builds)
621
656
 
622
657
  <!-- β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• -->
623
658
 
@@ -625,6 +660,7 @@
625
660
 
626
661
  <!-- ╔══════════════════════════════ END ══════════════════════════════╗ -->
627
662
 
663
+ <br>
628
664
  <br>
629
665
 
630
666
  ---