@cruxjs/app 0.0.4 β†’ 0.0.6

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,7 +8,7 @@
8
8
  </div>
9
9
 
10
10
  <div align="center">
11
- <img src="https://img.shields.io/badge/v-0.0.4-black"/>
11
+ <img src="https://img.shields.io/badge/v-0.0.6-black"/>
12
12
  <img src="https://img.shields.io/badge/πŸ”₯-@cruxjs-black"/>
13
13
  <br>
14
14
  <img src="https://img.shields.io/github/issues/cruxjs-org/app?style=flat" alt="Github Repo Issues" />
@@ -24,39 +24,65 @@
24
24
 
25
25
  - ## Quick Start πŸ”₯
26
26
 
27
- > **_Full-stack framework orchestrator for building modern web applications. Zero configuration. Plugin-based architecture._**
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._**
28
28
 
29
29
  - ### Setup
30
30
 
31
- > install [`hmm`](https://github.com/minejs-org/hmm) first.
31
+ > First, install [`hmm`](https://github.com/minejs-org/hmm) β€” the package manager for the CruxJS ecosystem.
32
32
 
33
33
  ```bash
34
+ # Install CruxJS App
34
35
  hmm i @cruxjs/app
35
- ```
36
36
 
37
- <div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
37
+ # Or install with plugins
38
+ hmm i @cruxjs/app @cruxplug/spa
39
+ ```
38
40
 
39
- - ### Usage
41
+ - ### Basic Usage
40
42
 
41
43
  ```typescript
42
44
  import { createApp, type AppConfig } from '@cruxjs/app';
43
45
 
44
- // Define your application
45
46
  const config: AppConfig = {
46
47
  debug: true,
48
+
49
+ // Server configuration
47
50
  server: {
48
51
  port: 3000,
49
52
  host: 'localhost'
50
53
  },
54
+
55
+ // Client build configuration (bundles with Bun)
51
56
  client: {
52
57
  entry: './src/client/browser.tsx',
53
- output: './dist/client',
54
- target: 'browser'
58
+ output: './src/shared/static/dist/js',
59
+ minify: true,
60
+ sourcemap: false
55
61
  },
56
- api: {
57
- directory: './src/server/api'
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
58
82
  },
59
- plugins: [] // Add plugins here
83
+
84
+ // Plugins (SPA, API routes, databases, etc.)
85
+ plugins: [/* your plugins */]
60
86
  };
61
87
 
62
88
  // Create and run the app
@@ -66,189 +92,493 @@
66
92
 
67
93
  <br>
68
94
 
69
- - ### 1. Define Routes
95
+ - ## Complete Example πŸ“–
70
96
 
71
- **src/server/api/index.ts**
72
- ```typescript
73
- import type { RouteDefinition } from '@cruxjs/app';
74
-
75
- export const routes: RouteDefinition[] = [
76
- {
77
- method: 'GET',
78
- path: '/api/users',
79
- handler: async (ctx) => {
80
- return ctx.json({ users: [] });
81
- }
82
- },
83
- {
84
- method: 'POST',
85
- path: '/api/users',
86
- handler: async (ctx) => {
87
- const data = await ctx.request.json();
88
- // Your logic here
89
- return ctx.json({ created: true }, { status: 201 });
90
- }
91
- }
92
- ];
93
- ```
97
+ ### Directory Structure
94
98
 
95
- - ### 2. Create Client Entry
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
+ ```
96
116
 
97
- **src/client/browser.tsx**
98
- ```typescript
99
- import { mount } from '@minejsx/runtime';
100
- import { App } from './ui/App';
101
- import { ClientManager } from '@cruxjs/client';
102
- import { HomePage } from './ui/pages/HomePage';
103
- import { NotFoundPage } from './ui/pages/NotFoundPage';
104
-
105
- // ClientManager is a pure management layer
106
- // You provide route components and error pages
107
- const clientManager = new ClientManager({
108
- debug: true,
109
- routes: {
110
- '/': HomePage,
111
- '/about': AboutPage,
112
- },
113
- notFoundComponent: NotFoundPage,
114
- errorComponent: ErrorPage
115
- });
116
-
117
- // Mount and run
118
- (async () => {
119
- await clientManager.boot();
120
- mount(<App />, '#app');
121
- await clientManager.ready('#app-main');
122
- })();
123
- ```
117
+ ### 1. Server Entry Point
124
118
 
125
- - ### 3. Add Plugins
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
+ ```
126
193
 
127
- ```typescript
128
- import { serverSPA } from '@cruxplug/spa';
129
-
130
- const spaPlugin = serverSPA({
131
- baseUrl: 'http://localhost:3000',
132
- clientEntry: './src/client/browser.tsx',
133
- clientScriptPath: '/static/dist/js/browser.js',
134
- pages: [
135
- {
136
- title: 'Home',
137
- path: '/',
138
- description: 'Welcome to my app',
139
- keywords: ['app', 'home']
140
- }
141
- ],
142
- errorPages: [
143
- {
144
- statusCode: 404,
145
- title: '404 - Not Found',
146
- path: '/404'
147
- }
148
- ]
149
- });
194
+ ### 2. Client Entry Point
150
195
 
151
- const config: AppConfig = {
152
- // ... other config
153
- plugins: [spaPlugin]
154
- };
155
- ```
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
+ ```
156
221
 
157
- <br>
222
+ ### 3. Define API Routes
158
223
 
159
- - ## Lifecycle πŸ”₯
224
+ **src/server/api/index.ts**
225
+ ```typescript
226
+ import type { RouteDefinition } from '@cruxjs/app';
227
+
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
+ ```
246
+
247
+ ### 4. Add Custom Styles
160
248
 
161
- CruxJS applications go through **4 phases**:
249
+ **src/client/ui/style/index.scss**
250
+ ```scss
251
+ // Import UI library variables (if available)
252
+ @import '@mineui/core/scss/variables';
253
+
254
+ // Custom styles
255
+ body {
256
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
257
+ margin: 0;
258
+ padding: 0;
259
+ }
260
+
261
+ .app {
262
+ display: flex;
263
+ flex-direction: column;
264
+ min-height: 100vh;
265
+ }
266
+
267
+ // More custom styles...
268
+ ```
269
+
270
+ - ## How It Works πŸ—οΈ
271
+
272
+ CruxJS orchestrates your full-stack application through **4 lifecycle phases**:
162
273
 
163
274
  - #### **Phase 0: REGISTER**
164
- > Plugins are registered and can hook into the application lifecycle.
275
+ Plugins register and declare their capabilities (routes, schemas, middleware).
165
276
 
166
277
  - #### **Phase 1: AWAKE**
167
- > Client is built, databases are initialized, i18n is setup, plugins initialize their schemas.
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
168
283
 
169
- **Hooks available:**
170
- ```typescript
171
- createApp(config, {
172
- onAwake: async (ctx) => {
173
- console.log('App is awake, databases ready');
174
- const db = ctx.databases.get('default');
175
- // Setup your initial data
176
- }
177
- });
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)
178
292
  ```
179
293
 
180
294
  - #### **Phase 2: START**
181
- > Server is created, routes are merged (user + plugin routes), middleware stack is built.
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
182
299
 
183
- **Hooks available:**
184
- ```typescript
185
- onStart: async (ctx) => {
186
- console.log('Server created, routes ready');
187
- console.log('Number of routes:', ctx.routes.length);
300
+ - #### **Phase 3: READY**
301
+ - Server is listening and ready to handle requests
302
+ - Plugins are fully operational
303
+
304
+ <br>
305
+
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
+ ```
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
+ });
360
+ ```
361
+
362
+ <br>
363
+
364
+ - ## Lifecycle Hooks πŸ”„
365
+
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
+ ```
401
+
402
+ <br>
403
+
404
+ - ## Plugins πŸ”Œ
405
+
406
+ Extend CruxJS with plugins. They integrate seamlessly into the lifecycle:
407
+
408
+ ```typescript
409
+ import type { CruxPlugin } from '@cruxjs/base';
410
+
411
+ const myPlugin: CruxPlugin = {
412
+ name: 'my-plugin',
413
+ version: '1.0.0',
414
+
415
+ // Provide routes
416
+ routes: [
417
+ {
418
+ method: 'GET',
419
+ path: '/plugin/status',
420
+ handler: async (ctx) => ctx.json({ status: 'ok' })
188
421
  }
189
- ```
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
+ ```
190
459
 
191
- - #### **Phase 3: READY**
192
- > Server is listening and ready to handle requests.
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...
193
463
 
194
- **Hooks available:**
195
- ```typescript
196
- onReady: async (ctx) => {
197
- const url = `http://${ctx.config.server.host}:${ctx.config.server.port}`;
198
- console.log(`πŸš€ Server ready at ${url}`);
464
+ <br>
465
+
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'
199
482
  }
200
- ```
483
+ ]
484
+ };
485
+
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
+ ```
491
+
492
+ <br>
493
+
494
+ - ## Internationalization (i18n) 🌍
495
+
496
+ Built-in multi-language support:
497
+
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
+ ```
508
+
509
+ **Directory structure:**
510
+ ```
511
+ src/shared/static/i18n/
512
+ β”œβ”€β”€ en.json
513
+ β”œβ”€β”€ ar.json
514
+ β”œβ”€β”€ fr.json
515
+ └── es.json
516
+ ```
201
517
 
202
518
  <br>
203
519
 
204
520
  - ## Configuration πŸ”₯
205
521
 
206
- ### AppConfig
522
+ ### AppConfig Interface
207
523
 
208
524
  ```typescript
209
525
  interface AppConfig {
210
- // Debug mode
526
+ // Enable debug mode (affects minification, sourcemaps)
211
527
  debug?: boolean;
212
528
 
213
529
  // Server configuration
214
530
  server?: {
215
531
  port?: number; // Default: 3000
216
532
  host?: string; // Default: 'localhost'
217
- logging?: LoggingConfig;
533
+ logging?: {
534
+ level?: 'debug' | 'info' | 'warn' | 'error';
535
+ pretty?: boolean;
536
+ };
218
537
  };
219
538
 
220
- // Client build configuration
539
+ // Client build (Bun bundler)
221
540
  client?: {
222
- entry: string; // Client entry point (e.g., './src/client/browser.tsx')
541
+ entry: string; // Entry point (e.g., './src/client/browser.tsx')
223
542
  output: string; // Output directory
224
- target?: 'browser' | 'bun'; // Default: 'browser'
225
- minify?: boolean; // Default: !debug
226
- sourcemap?: boolean; // Default: debug
227
- external?: string[]; // External dependencies to exclude from bundle
543
+ target?: 'browser' | 'bun';
544
+ minify?: boolean; // Default: !debug
545
+ sourcemap?: boolean; // Default: debug
546
+ external?: string[]; // Don't bundle these
228
547
  };
229
548
 
230
- // API routes configuration
231
- api?: {
232
- directory: string; // Directory to scan for route files
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
233
569
  };
234
570
 
235
571
  // Database configuration
236
572
  database?: DatabaseConfig | DatabaseConfig[];
237
573
 
238
- // Internationalization configuration
574
+ // Internationalization
239
575
  i18n?: {
240
576
  defaultLanguage: string;
241
577
  supportedLanguages: string[];
242
578
  basePath?: string;
243
- fileExtension?: string; // Default: 'json'
579
+ fileExtension?: string; // Default: 'json'
244
580
  };
245
581
 
246
- // Static files serving
247
- static?: StaticConfig | StaticConfig[];
248
-
249
- // Security configuration
250
- security?: SecurityConfig;
251
-
252
582
  // Inline routes
253
583
  routes?: RouteDefinition[];
254
584
 
@@ -262,186 +592,32 @@
262
592
 
263
593
  <br>
264
594
 
595
+ <br>
596
+
265
597
  - ## API Reference πŸ”₯
266
598
 
267
599
  ### Core Function
268
600
 
269
- - #### `createApp(config: AppConfig, hooks?: LifecycleHooks): AppInstance`
270
- > Creates and returns an application instance.
271
-
272
- **Parameters:**
273
- - `config` - Application configuration
274
- - `hooks` (optional) - Lifecycle hooks
275
-
276
- **Returns:** AppInstance with `start()`, `stop()`, `restart()` methods
277
-
278
- **Example:**
279
- ```typescript
280
- const app = createApp({
281
- debug: true,
282
- server: { port: 3000 }
283
- }, {
284
- onAwake: async (ctx) => console.log('awake'),
285
- onStart: async (ctx) => console.log('start'),
286
- onReady: async (ctx) => console.log('ready'),
287
- onFinish: async (ctx) => console.log('done'),
288
- onError: async (ctx, phase, error) => console.error(error)
289
- });
290
-
291
- await app.start();
292
- ```
293
-
294
- ### AppInstance
295
-
296
- - #### `app.start(): Promise<void>`
297
- > Starts the application through all lifecycle phases (REGISTER β†’ AWAKE β†’ START β†’ READY).
298
-
299
- - #### `app.stop(): Promise<void>`
300
- > Stops the server and cleans up all resources.
301
-
302
- - #### `app.restart(): Promise<void>`
303
- > Restarts the application (stops then starts).
304
-
305
- - #### `app.getContext(): LifecycleContext`
306
- > Returns the current lifecycle context with databases, plugins, and configuration.
307
-
308
- - #### `app.getMiddleware(name: string): AppMiddleware | undefined`
309
- > Retrieves a registered middleware by name.
310
-
311
- ### LifecycleHooks
312
-
313
601
  ```typescript
314
- interface LifecycleHooks {
315
- onConfig?(config: AppConfig): AppConfig;
316
- onAwake?(ctx: LifecycleContext): Promise<void>;
317
- onStart?(ctx: LifecycleContext): Promise<void>;
318
- onReady?(ctx: LifecycleContext): Promise<void>;
319
- onFinish?(ctx: LifecycleContext): Promise<void>;
320
- onError?(ctx: LifecycleContext, phase: string, error: Error): Promise<void>;
321
- }
322
- ```
602
+ import { createApp, type AppConfig } from '@cruxjs/app';
323
603
 
324
- ### LifecycleContext
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
+ });
325
611
 
326
- ```typescript
327
- interface LifecycleContext {
328
- config: AppConfig;
329
- server: ServerInstance | null;
330
- databases: Map<string, DB>;
331
- plugins: CruxPlugin[];
332
- clientBuild?: any;
333
- }
612
+ await app.start();
334
613
  ```
335
614
 
336
- <br>
337
-
338
- - ## Advanced Features πŸš€
339
-
340
- - #### Plugin System
341
- > CruxJS uses a plugin-based architecture. Plugins can:
342
- - Provide routes
343
- - Define database schemas
344
- - Register middleware
345
- - Hook into lifecycle events
346
-
347
- **Example - Creating a Plugin:**
348
- ```typescript
349
- import type { CruxPlugin } from '@cruxjs/base';
350
-
351
- const myPlugin: CruxPlugin = {
352
- name: 'my-plugin',
353
- version: '1.0.0',
354
-
355
- register: async (app) => {
356
- console.log('Plugin registered');
357
- },
358
-
359
- routes: [
360
- {
361
- method: 'GET',
362
- path: '/my-plugin/status',
363
- handler: async (ctx) => ctx.json({ status: 'ok' })
364
- }
365
- ],
366
-
367
- schemas: [
368
- {
369
- name: 'my_table',
370
- columns: [
371
- { name: 'id', type: 'INTEGER PRIMARY KEY' },
372
- { name: 'data', type: 'TEXT' }
373
- ]
374
- }
375
- ],
376
-
377
- middleware: {
378
- 'my-middleware': async (ctx, next) => {
379
- console.log('Custom middleware');
380
- return next();
381
- }
382
- },
383
-
384
- hooks: {
385
- onAwake: async (ctx) => console.log('Plugin awake'),
386
- onStart: async (ctx) => console.log('Plugin start'),
387
- onReady: async (ctx) => console.log('Plugin ready'),
388
- onShutdown: async (ctx) => console.log('Plugin shutdown')
389
- }
390
- };
391
- ```
392
-
393
- - #### Multiple Databases
394
- > Support for multiple database connections:
395
- ```typescript
396
- const config: AppConfig = {
397
- database: [
398
- {
399
- name: 'primary',
400
- connection: './data/primary.db',
401
- schema: './src/schemas/primary.ts'
402
- },
403
- {
404
- name: 'cache',
405
- connection: './data/cache.db',
406
- schema: './src/schemas/cache.ts'
407
- }
408
- ]
409
- };
615
+ ### AppInstance Methods
410
616
 
411
- const app = createApp(config);
412
- await app.start();
413
-
414
- // Access databases
415
- const primaryDb = app.databases.get('primary');
416
- const cacheDb = app.databases.get('cache');
417
- ```
418
-
419
- - #### Client Building
420
- > Automatic client bundle generation using Bun:
421
- ```typescript
422
- const config: AppConfig = {
423
- client: {
424
- entry: './src/client/browser.tsx',
425
- output: './dist/client',
426
- minify: true,
427
- sourcemap: false,
428
- external: ['@minejsx/runtime'] // Don't bundle, rely on external
429
- }
430
- };
431
- ```
432
-
433
- - #### i18n Integration
434
- > Built-in internationalization support:
435
- ```typescript
436
- const config: AppConfig = {
437
- i18n: {
438
- defaultLanguage: 'en',
439
- supportedLanguages: ['en', 'ar', 'fr'],
440
- basePath: './src/shared/static/i18n',
441
- fileExtension: 'json'
442
- }
443
- };
444
- ```
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
445
621
 
446
622
  <!-- β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• -->
447
623