jsgui3-server 0.0.138 → 0.0.140
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/AGENTS.md +87 -0
- package/README.md +12 -0
- package/docs/GUIDE_TO_AGENTIC_WORKFLOWS_BY_GROK.md +19 -0
- package/docs/advanced-usage-examples.md +1360 -0
- package/docs/agent-development-guide.md +386 -0
- package/docs/api-reference.md +916 -0
- package/docs/broken-functionality-tracker.md +285 -0
- package/docs/bundling-system-deep-dive.md +525 -0
- package/docs/cli-reference.md +393 -0
- package/docs/comprehensive-documentation.md +1403 -0
- package/docs/configuration-reference.md +808 -0
- package/docs/controls-development.md +859 -0
- package/docs/documentation-review/CURRENT_REVIEW.md +95 -0
- package/docs/function-publishers-json-apis.md +847 -0
- package/docs/getting-started-with-json.md +518 -0
- package/docs/minification-compression-sourcemaps-status.md +482 -0
- package/docs/minification-compression-sourcemaps-test-results.md +205 -0
- package/docs/publishers-guide.md +313 -0
- package/docs/resources-guide.md +615 -0
- package/docs/serve-helpers.md +406 -0
- package/docs/simple-server-api-design.md +13 -0
- package/docs/system-architecture.md +275 -0
- package/docs/troubleshooting.md +698 -0
- package/examples/json/README.md +115 -0
- package/examples/json/basic-api/README.md +345 -0
- package/examples/json/basic-api/server.js +199 -0
- package/examples/json/simple-api/README.md +125 -0
- package/examples/json/simple-api/diagnostic-report.json +73 -0
- package/examples/json/simple-api/diagnostic-test.js +433 -0
- package/examples/json/simple-api/server-debug.md +58 -0
- package/examples/json/simple-api/server.js +91 -0
- package/examples/json/simple-api/test.js +215 -0
- package/http/responders/static/Static_Route_HTTP_Responder.js +1 -2
- package/package.json +19 -8
- package/publishers/helpers/assigners/static-compressed-response-buffers/Single_Control_Webpage_Server_Static_Compressed_Response_Buffers_Assigner.js +65 -12
- package/publishers/helpers/preparers/static/bundle/Static_Routes_Responses_Webpage_Bundle_Preparer.js +6 -1
- package/publishers/http-function-publisher.js +59 -38
- package/publishers/http-webpage-publisher.js +48 -1
- package/resources/processors/bundlers/js/esbuild/Advanced_JS_Bundler_Using_ESBuild.js +38 -146
- package/resources/processors/bundlers/js/esbuild/Core_JS_Non_Minifying_Bundler_Using_ESBuild.js +54 -5
- package/resources/processors/bundlers/js/esbuild/Core_JS_Single_File_Minifying_Bundler_Using_ESBuild.js +36 -4
- package/serve-factory.js +36 -9
- package/server.js +10 -4
- package/test-report.json +0 -0
- package/tests/README.md +250 -0
- package/tests/assigners.test.js +316 -0
- package/tests/bundlers.test.js +329 -0
- package/tests/configuration-validation.test.js +530 -0
- package/tests/content-analysis.test.js +641 -0
- package/tests/end-to-end.test.js +496 -0
- package/tests/error-handling.test.js +746 -0
- package/tests/performance.test.js +653 -0
- package/tests/publishers.test.js +395 -0
- package/tests/temp_invalid.js +7 -0
- package/tests/temp_invalid_utf8.js +1 -0
- package/tests/temp_malformed.js +10 -0
- package/tests/test-runner.js +261 -0
|
@@ -0,0 +1,808 @@
|
|
|
1
|
+
# Configuration Reference
|
|
2
|
+
|
|
3
|
+
## When to Read
|
|
4
|
+
|
|
5
|
+
This document provides comprehensive reference for all JSGUI3 Server configuration options. Read this when:
|
|
6
|
+
- You need detailed information about every configuration option
|
|
7
|
+
- You're setting up complex server configurations
|
|
8
|
+
- You want to understand option precedence and validation
|
|
9
|
+
- You're migrating from legacy configuration patterns
|
|
10
|
+
- You need to configure advanced features like CORS, SSL, or custom publishers
|
|
11
|
+
|
|
12
|
+
**Note:** For basic usage, see [README.md](../README.md). For CLI usage, see [docs/cli-reference.md](docs/cli-reference.md).
|
|
13
|
+
|
|
14
|
+
## Overview
|
|
15
|
+
|
|
16
|
+
JSGUI3 Server supports multiple configuration methods with different precedence levels. Configuration can be provided programmatically, via environment variables, configuration files, or CLI options.
|
|
17
|
+
|
|
18
|
+
## Configuration Sources and Precedence
|
|
19
|
+
|
|
20
|
+
Configuration values are resolved in this order (later sources override earlier ones):
|
|
21
|
+
|
|
22
|
+
1. **Built-in defaults** - Framework defaults
|
|
23
|
+
2. **Environment variables** - `PORT`, `HOST`, `JSGUI_DEBUG`
|
|
24
|
+
3. **Configuration files** - `jsgui.config.js` (if present)
|
|
25
|
+
4. **CLI options** - `--port`, `--host`, `--root`
|
|
26
|
+
5. **Programmatic options** - `Server.serve(options)` parameters
|
|
27
|
+
|
|
28
|
+
## Server.serve() Options
|
|
29
|
+
|
|
30
|
+
### Core Options
|
|
31
|
+
|
|
32
|
+
#### `ctrl` / `Ctrl`
|
|
33
|
+
- **Type:** `Function`
|
|
34
|
+
- **Description:** Main control class constructor to serve
|
|
35
|
+
- **Default:** Auto-discovered from client.js
|
|
36
|
+
- **Example:**
|
|
37
|
+
```javascript
|
|
38
|
+
Server.serve({
|
|
39
|
+
ctrl: MyControl
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
#### `src_path_client_js`
|
|
44
|
+
- **Type:** `string`
|
|
45
|
+
- **Description:** Path to client-side JavaScript file
|
|
46
|
+
- **Default:** Auto-discovered (client.js, src/client.js, app/client.js)
|
|
47
|
+
- **Example:**
|
|
48
|
+
```javascript
|
|
49
|
+
Server.serve({
|
|
50
|
+
src_path_client_js: require.resolve('./my-client.js')
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
#### `port`
|
|
55
|
+
- **Type:** `number`
|
|
56
|
+
- **Description:** HTTP server port
|
|
57
|
+
- **Default:** `8080` (or `process.env.PORT`)
|
|
58
|
+
- **Special values:** `0` = random available port
|
|
59
|
+
- **Example:**
|
|
60
|
+
```javascript
|
|
61
|
+
Server.serve({ port: 3000 });
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
#### `host`
|
|
65
|
+
- **Type:** `string`
|
|
66
|
+
- **Description:** Host interface to bind to
|
|
67
|
+
- **Default:** All IPv4 interfaces (or `process.env.HOST`)
|
|
68
|
+
- **Example:**
|
|
69
|
+
```javascript
|
|
70
|
+
Server.serve({
|
|
71
|
+
host: '127.0.0.1' // localhost only
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### `debug`
|
|
76
|
+
- **Type:** `boolean`
|
|
77
|
+
- **Description:** Enable debug mode with verbose logging and source maps
|
|
78
|
+
- **Default:** `false` (or `truthy(process.env.JSGUI_DEBUG)`)
|
|
79
|
+
- **Example:**
|
|
80
|
+
```javascript
|
|
81
|
+
Server.serve({ debug: true });
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Page Configuration
|
|
85
|
+
|
|
86
|
+
#### `page`
|
|
87
|
+
- **Type:** `object`
|
|
88
|
+
- **Description:** Single page configuration with metadata
|
|
89
|
+
- **Properties:**
|
|
90
|
+
- `content`: Control constructor (required)
|
|
91
|
+
- `title`: HTML page title (optional)
|
|
92
|
+
- `description`: Meta description (optional)
|
|
93
|
+
- `path`: URL path (default: '/')
|
|
94
|
+
- `favicon`: Path to favicon file (optional)
|
|
95
|
+
- **Example:**
|
|
96
|
+
```javascript
|
|
97
|
+
Server.serve({
|
|
98
|
+
page: {
|
|
99
|
+
content: HomeControl,
|
|
100
|
+
title: 'My App - Home',
|
|
101
|
+
description: 'Welcome to my application',
|
|
102
|
+
favicon: './favicon.ico'
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
#### `pages`
|
|
108
|
+
- **Type:** `object`
|
|
109
|
+
- **Description:** Multiple page configuration
|
|
110
|
+
- **Keys:** URL paths (strings)
|
|
111
|
+
- **Values:** Page configuration objects (same as `page` option)
|
|
112
|
+
- **Example:**
|
|
113
|
+
```javascript
|
|
114
|
+
Server.serve({
|
|
115
|
+
pages: {
|
|
116
|
+
'/': {
|
|
117
|
+
content: HomeControl,
|
|
118
|
+
title: 'Home'
|
|
119
|
+
},
|
|
120
|
+
'/about': {
|
|
121
|
+
content: AboutControl,
|
|
122
|
+
title: 'About Us'
|
|
123
|
+
},
|
|
124
|
+
'/contact': {
|
|
125
|
+
content: ContactControl,
|
|
126
|
+
title: 'Contact'
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### API Configuration
|
|
133
|
+
|
|
134
|
+
#### `api`
|
|
135
|
+
- **Type:** `object`
|
|
136
|
+
- **Description:** REST API endpoint definitions
|
|
137
|
+
- **Keys:** Route suffixes (automatically prefixed with `/api/`)
|
|
138
|
+
- **Values:** Handler functions
|
|
139
|
+
- **Handler signatures:**
|
|
140
|
+
- Synchronous: `() => any`
|
|
141
|
+
- Asynchronous: `async () => Promise<any>`
|
|
142
|
+
- With parameters: `({ param1, param2 }) => any`
|
|
143
|
+
- **Response types:**
|
|
144
|
+
- Objects/Arrays → `application/json`
|
|
145
|
+
- Strings → `text/plain`
|
|
146
|
+
- Promises → automatically awaited
|
|
147
|
+
- **Example:**
|
|
148
|
+
```javascript
|
|
149
|
+
Server.serve({
|
|
150
|
+
api: {
|
|
151
|
+
'users': async () => await getUsers(),
|
|
152
|
+
'user': ({ id }) => getUserById(id),
|
|
153
|
+
'status': () => ({ uptime: process.uptime() }),
|
|
154
|
+
'echo': (data) => data
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Static File Serving
|
|
160
|
+
|
|
161
|
+
#### `static`
|
|
162
|
+
- **Type:** `object`
|
|
163
|
+
- **Description:** Static file directory mappings
|
|
164
|
+
- **Keys:** URL prefixes
|
|
165
|
+
- **Values:** Local directory paths
|
|
166
|
+
- **Example:**
|
|
167
|
+
```javascript
|
|
168
|
+
Server.serve({
|
|
169
|
+
static: {
|
|
170
|
+
'/images': './public/images',
|
|
171
|
+
'/css': './assets/css',
|
|
172
|
+
'/js': './dist/js'
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Advanced Options
|
|
178
|
+
|
|
179
|
+
#### `name`
|
|
180
|
+
- **Type:** `string`
|
|
181
|
+
- **Description:** Server instance name (for logging)
|
|
182
|
+
- **Default:** `'jsgui3-server'`
|
|
183
|
+
- **Example:**
|
|
184
|
+
```javascript
|
|
185
|
+
Server.serve({
|
|
186
|
+
name: 'My Production Server'
|
|
187
|
+
});
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
#### `root`
|
|
191
|
+
- **Type:** `string`
|
|
192
|
+
- **Description:** Project root directory
|
|
193
|
+
- **Default:** Current working directory
|
|
194
|
+
- **Example:**
|
|
195
|
+
```javascript
|
|
196
|
+
Server.serve({
|
|
197
|
+
root: '/path/to/project'
|
|
198
|
+
});
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
#### `config`
|
|
202
|
+
- **Type:** `string`
|
|
203
|
+
- **Description:** Path to configuration file
|
|
204
|
+
- **Default:** `'jsgui.config.js'` (if exists)
|
|
205
|
+
- **Example:**
|
|
206
|
+
```javascript
|
|
207
|
+
Server.serve({
|
|
208
|
+
config: './my-config.js'
|
|
209
|
+
});
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Environment Variables
|
|
213
|
+
|
|
214
|
+
### PORT
|
|
215
|
+
- **Type:** `number`
|
|
216
|
+
- **Description:** HTTP server port
|
|
217
|
+
- **Default:** `8080`
|
|
218
|
+
- **Example:** `PORT=3000 node server.js`
|
|
219
|
+
|
|
220
|
+
### HOST
|
|
221
|
+
- **Type:** `string`
|
|
222
|
+
- **Description:** Host interface to bind to
|
|
223
|
+
- **Default:** All IPv4 interfaces
|
|
224
|
+
- **Example:** `HOST=127.0.0.1 node server.js`
|
|
225
|
+
|
|
226
|
+
### JSGUI_DEBUG
|
|
227
|
+
- **Type:** `boolean` (truthy)
|
|
228
|
+
- **Description:** Enable debug mode
|
|
229
|
+
- **Values:** `1`, `true`, `yes` = enabled; `0`, `false`, `no` = disabled
|
|
230
|
+
- **Example:** `JSGUI_DEBUG=1 node server.js`
|
|
231
|
+
|
|
232
|
+
## Configuration Files
|
|
233
|
+
|
|
234
|
+
### jsgui.config.js
|
|
235
|
+
|
|
236
|
+
Configuration files can contain any `Server.serve()` options:
|
|
237
|
+
|
|
238
|
+
```javascript
|
|
239
|
+
module.exports = {
|
|
240
|
+
port: 3000,
|
|
241
|
+
host: 'localhost',
|
|
242
|
+
debug: process.env.NODE_ENV === 'development',
|
|
243
|
+
|
|
244
|
+
pages: {
|
|
245
|
+
'/': {
|
|
246
|
+
content: require('./controls/home'),
|
|
247
|
+
title: 'Home'
|
|
248
|
+
},
|
|
249
|
+
'/admin': {
|
|
250
|
+
content: require('./controls/admin'),
|
|
251
|
+
title: 'Admin Panel'
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
|
|
255
|
+
api: {
|
|
256
|
+
'health': () => ({ status: 'ok' }),
|
|
257
|
+
'metrics': () => collectMetrics()
|
|
258
|
+
},
|
|
259
|
+
|
|
260
|
+
static: {
|
|
261
|
+
'/assets': './public/assets'
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Configuration File Resolution
|
|
267
|
+
|
|
268
|
+
1. **Automatic discovery:** Looks for `jsgui.config.js` in current directory
|
|
269
|
+
2. **Explicit path:** Specified via `config` option
|
|
270
|
+
3. **Merging:** Configuration file options are merged with programmatic options
|
|
271
|
+
4. **Precedence:** Programmatic options override configuration file options
|
|
272
|
+
|
|
273
|
+
## Advanced Configuration
|
|
274
|
+
|
|
275
|
+
### CORS Configuration
|
|
276
|
+
|
|
277
|
+
```javascript
|
|
278
|
+
Server.serve({
|
|
279
|
+
cors: {
|
|
280
|
+
origin: ['http://localhost:3000', 'https://myapp.com'],
|
|
281
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE'],
|
|
282
|
+
credentials: true,
|
|
283
|
+
maxAge: 86400 // 24 hours
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### SSL/TLS Configuration
|
|
289
|
+
|
|
290
|
+
```javascript
|
|
291
|
+
const fs = require('fs');
|
|
292
|
+
|
|
293
|
+
Server.serve({
|
|
294
|
+
port: 443,
|
|
295
|
+
https: {
|
|
296
|
+
key: fs.readFileSync('./ssl/private.key'),
|
|
297
|
+
cert: fs.readFileSync('./ssl/certificate.crt'),
|
|
298
|
+
ca: fs.readFileSync('./ssl/ca-bundle.crt')
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Custom Publishers
|
|
304
|
+
|
|
305
|
+
```javascript
|
|
306
|
+
const CustomPublisher = require('./custom-publisher');
|
|
307
|
+
|
|
308
|
+
Server.serve({
|
|
309
|
+
publishers: {
|
|
310
|
+
'/api/graphql': new CustomPublisher({
|
|
311
|
+
schema: myGraphQLSchema
|
|
312
|
+
})
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Resource Pools
|
|
318
|
+
|
|
319
|
+
```javascript
|
|
320
|
+
Server.serve({
|
|
321
|
+
resources: {
|
|
322
|
+
database: new DatabaseResource({
|
|
323
|
+
connectionString: process.env.DATABASE_URL
|
|
324
|
+
}),
|
|
325
|
+
cache: new RedisResource({
|
|
326
|
+
host: 'localhost',
|
|
327
|
+
port: 6379
|
|
328
|
+
})
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Middleware
|
|
334
|
+
|
|
335
|
+
```javascript
|
|
336
|
+
const express = require('express');
|
|
337
|
+
const compression = require('compression');
|
|
338
|
+
|
|
339
|
+
Server.serve({
|
|
340
|
+
middleware: [
|
|
341
|
+
compression(),
|
|
342
|
+
express.json({ limit: '10mb' }),
|
|
343
|
+
(req, res, next) => {
|
|
344
|
+
console.log(`${req.method} ${req.url}`);
|
|
345
|
+
next();
|
|
346
|
+
}
|
|
347
|
+
]
|
|
348
|
+
});
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
## Configuration Validation
|
|
352
|
+
|
|
353
|
+
### Type Checking
|
|
354
|
+
|
|
355
|
+
The server validates configuration options and provides helpful error messages:
|
|
356
|
+
|
|
357
|
+
```javascript
|
|
358
|
+
// Valid
|
|
359
|
+
Server.serve({ port: 3000 });
|
|
360
|
+
|
|
361
|
+
// Invalid - will throw error
|
|
362
|
+
Server.serve({ port: 'not-a-number' });
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Required vs Optional
|
|
366
|
+
|
|
367
|
+
- **Required:** None (auto-discovery provides defaults)
|
|
368
|
+
- **Optional:** All options have sensible defaults
|
|
369
|
+
|
|
370
|
+
### Validation Rules
|
|
371
|
+
|
|
372
|
+
- `port`: Must be number between 1-65535 or 0 (ephemeral)
|
|
373
|
+
- `host`: Must be valid IPv4 address or hostname
|
|
374
|
+
- `debug`: Converted to boolean using truthy() function
|
|
375
|
+
- `pages`: Each page must have `content` property
|
|
376
|
+
- `api`: Values must be functions
|
|
377
|
+
- `static`: Values must be strings (directory paths)
|
|
378
|
+
|
|
379
|
+
## Configuration Patterns
|
|
380
|
+
|
|
381
|
+
### Development vs Production
|
|
382
|
+
|
|
383
|
+
```javascript
|
|
384
|
+
// Development
|
|
385
|
+
const devConfig = {
|
|
386
|
+
port: 3000,
|
|
387
|
+
debug: true,
|
|
388
|
+
cors: { origin: true }
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
// Production
|
|
392
|
+
const prodConfig = {
|
|
393
|
+
port: process.env.PORT || 80,
|
|
394
|
+
debug: false,
|
|
395
|
+
cors: {
|
|
396
|
+
origin: ['https://myapp.com']
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
const config = process.env.NODE_ENV === 'production' ? prodConfig : devConfig;
|
|
401
|
+
Server.serve(config);
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Multi-Environment Configuration
|
|
405
|
+
|
|
406
|
+
```javascript
|
|
407
|
+
const baseConfig = {
|
|
408
|
+
pages: { /* ... */ },
|
|
409
|
+
api: { /* ... */ }
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
const configs = {
|
|
413
|
+
development: {
|
|
414
|
+
...baseConfig,
|
|
415
|
+
port: 3000,
|
|
416
|
+
debug: true
|
|
417
|
+
},
|
|
418
|
+
staging: {
|
|
419
|
+
...baseConfig,
|
|
420
|
+
port: 8080,
|
|
421
|
+
debug: false
|
|
422
|
+
},
|
|
423
|
+
production: {
|
|
424
|
+
...baseConfig,
|
|
425
|
+
port: 80,
|
|
426
|
+
debug: false,
|
|
427
|
+
host: '0.0.0.0'
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
const env = process.env.NODE_ENV || 'development';
|
|
432
|
+
Server.serve(configs[env]);
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
### Configuration Factories
|
|
436
|
+
|
|
437
|
+
```javascript
|
|
438
|
+
function createServerConfig(options = {}) {
|
|
439
|
+
const defaults = {
|
|
440
|
+
port: process.env.PORT || 8080,
|
|
441
|
+
debug: truthy(process.env.JSGUI_DEBUG),
|
|
442
|
+
host: process.env.HOST
|
|
443
|
+
};
|
|
444
|
+
|
|
445
|
+
return {
|
|
446
|
+
...defaults,
|
|
447
|
+
...options,
|
|
448
|
+
pages: {
|
|
449
|
+
'/': {
|
|
450
|
+
content: require('./controls/app'),
|
|
451
|
+
title: options.title || 'My App'
|
|
452
|
+
},
|
|
453
|
+
...options.pages
|
|
454
|
+
},
|
|
455
|
+
api: {
|
|
456
|
+
health: () => ({ status: 'ok', timestamp: new Date() }),
|
|
457
|
+
...options.api
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
Server.serve(createServerConfig({
|
|
463
|
+
title: 'Dashboard',
|
|
464
|
+
port: 3000
|
|
465
|
+
}));
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
## Migration from Legacy API
|
|
469
|
+
|
|
470
|
+
### Old Server Constructor
|
|
471
|
+
|
|
472
|
+
```javascript
|
|
473
|
+
// Legacy (still supported)
|
|
474
|
+
const server = new Server({
|
|
475
|
+
Ctrl: MyControl,
|
|
476
|
+
src_path_client_js: require.resolve('./client.js')
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
server.on('ready', () => {
|
|
480
|
+
server.start(8080);
|
|
481
|
+
});
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
### New Server.serve() API
|
|
485
|
+
|
|
486
|
+
```javascript
|
|
487
|
+
// New (recommended)
|
|
488
|
+
Server.serve({
|
|
489
|
+
ctrl: MyControl,
|
|
490
|
+
port: 8080
|
|
491
|
+
});
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### Migration Benefits
|
|
495
|
+
|
|
496
|
+
- **Simpler:** No event handling required
|
|
497
|
+
- **Promise-based:** Better async handling
|
|
498
|
+
- **Auto-discovery:** Less boilerplate
|
|
499
|
+
- **Environment-aware:** Respects environment variables
|
|
500
|
+
- **Consistent:** Same API for all use cases
|
|
501
|
+
|
|
502
|
+
## Debugging Configuration
|
|
503
|
+
|
|
504
|
+
### Configuration Logging
|
|
505
|
+
|
|
506
|
+
Enable debug mode to see resolved configuration:
|
|
507
|
+
|
|
508
|
+
```bash
|
|
509
|
+
JSGUI_DEBUG=1 node cli.js serve
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
This will log:
|
|
513
|
+
- Resolved configuration values
|
|
514
|
+
- Auto-discovered file paths
|
|
515
|
+
- Environment variable usage
|
|
516
|
+
- Configuration file loading
|
|
517
|
+
|
|
518
|
+
### Configuration Inspection
|
|
519
|
+
|
|
520
|
+
```javascript
|
|
521
|
+
// Inspect resolved configuration
|
|
522
|
+
const server = await Server.serve({ debug: true });
|
|
523
|
+
console.log('Resolved config:', server.config);
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
### Validation Errors
|
|
527
|
+
|
|
528
|
+
Common validation errors and solutions:
|
|
529
|
+
|
|
530
|
+
```
|
|
531
|
+
Error: Invalid port number: "abc"
|
|
532
|
+
Solution: Use a number: port: 3000
|
|
533
|
+
|
|
534
|
+
Error: Page missing content property
|
|
535
|
+
Solution: pages: { '/': { content: MyControl, title: 'Home' } }
|
|
536
|
+
|
|
537
|
+
Error: API handler must be a function
|
|
538
|
+
Solution: api: { 'endpoint': () => 'response' }
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
## Performance Tuning
|
|
542
|
+
|
|
543
|
+
### Bundling Options
|
|
544
|
+
|
|
545
|
+
```javascript
|
|
546
|
+
Server.serve({
|
|
547
|
+
bundler: {
|
|
548
|
+
minify: !debug,
|
|
549
|
+
sourcemap: debug,
|
|
550
|
+
target: 'es2018',
|
|
551
|
+
external: ['react', 'lodash']
|
|
552
|
+
}
|
|
553
|
+
});
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
### Caching Configuration
|
|
557
|
+
|
|
558
|
+
```javascript
|
|
559
|
+
Server.serve({
|
|
560
|
+
cache: {
|
|
561
|
+
static: {
|
|
562
|
+
maxAge: 86400 // 24 hours
|
|
563
|
+
},
|
|
564
|
+
api: {
|
|
565
|
+
maxAge: 300 // 5 minutes
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
});
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
### Connection Pooling
|
|
572
|
+
|
|
573
|
+
```javascript
|
|
574
|
+
Server.serve({
|
|
575
|
+
pool: {
|
|
576
|
+
maxConnections: 100,
|
|
577
|
+
idleTimeout: 30000,
|
|
578
|
+
acquireTimeout: 60000
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
## Security Configuration
|
|
584
|
+
|
|
585
|
+
### HTTPS Enforcement
|
|
586
|
+
|
|
587
|
+
```javascript
|
|
588
|
+
Server.serve({
|
|
589
|
+
https: {
|
|
590
|
+
force: true, // Redirect HTTP to HTTPS
|
|
591
|
+
hsts: {
|
|
592
|
+
maxAge: 31536000, // 1 year
|
|
593
|
+
includeSubDomains: true
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
});
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
### Rate Limiting
|
|
600
|
+
|
|
601
|
+
```javascript
|
|
602
|
+
Server.serve({
|
|
603
|
+
rateLimit: {
|
|
604
|
+
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
605
|
+
max: 100, // limit each IP to 100 requests per windowMs
|
|
606
|
+
message: 'Too many requests from this IP'
|
|
607
|
+
}
|
|
608
|
+
});
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
### Input Validation
|
|
612
|
+
|
|
613
|
+
```javascript
|
|
614
|
+
Server.serve({
|
|
615
|
+
validation: {
|
|
616
|
+
api: {
|
|
617
|
+
maxBodySize: '10mb',
|
|
618
|
+
allowedTypes: ['application/json', 'text/plain']
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
});
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
## Monitoring and Observability
|
|
625
|
+
|
|
626
|
+
### Logging Configuration
|
|
627
|
+
|
|
628
|
+
```javascript
|
|
629
|
+
Server.serve({
|
|
630
|
+
logging: {
|
|
631
|
+
level: 'info', // error, warn, info, debug
|
|
632
|
+
format: 'json', // json, simple, detailed
|
|
633
|
+
file: './logs/server.log',
|
|
634
|
+
maxSize: '10m',
|
|
635
|
+
maxFiles: 5
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
### Metrics Collection
|
|
641
|
+
|
|
642
|
+
```javascript
|
|
643
|
+
Server.serve({
|
|
644
|
+
metrics: {
|
|
645
|
+
enabled: true,
|
|
646
|
+
endpoint: '/metrics',
|
|
647
|
+
format: 'prometheus', // prometheus, json, statsd
|
|
648
|
+
labels: {
|
|
649
|
+
service: 'jsgui3-server',
|
|
650
|
+
version: '1.0.0'
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
});
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
### Health Checks
|
|
657
|
+
|
|
658
|
+
```javascript
|
|
659
|
+
Server.serve({
|
|
660
|
+
health: {
|
|
661
|
+
enabled: true,
|
|
662
|
+
endpoint: '/health',
|
|
663
|
+
checks: {
|
|
664
|
+
database: () => checkDatabaseConnection(),
|
|
665
|
+
filesystem: () => checkDiskSpace()
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
});
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
## Extending Configuration
|
|
672
|
+
|
|
673
|
+
### Custom Configuration Loaders
|
|
674
|
+
|
|
675
|
+
```javascript
|
|
676
|
+
class YamlConfigLoader {
|
|
677
|
+
static load(path) {
|
|
678
|
+
const yaml = require('js-yaml');
|
|
679
|
+
const fs = require('fs');
|
|
680
|
+
const content = fs.readFileSync(path, 'utf8');
|
|
681
|
+
return yaml.load(content);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
Server.serve({
|
|
686
|
+
config: './config.yml',
|
|
687
|
+
configLoader: YamlConfigLoader
|
|
688
|
+
});
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
### Configuration Plugins
|
|
692
|
+
|
|
693
|
+
```javascript
|
|
694
|
+
class DatabaseConfigPlugin {
|
|
695
|
+
apply(config) {
|
|
696
|
+
if (!config.api) config.api = {};
|
|
697
|
+
|
|
698
|
+
config.api.database = {
|
|
699
|
+
status: () => checkDatabaseHealth(),
|
|
700
|
+
backup: () => triggerBackup()
|
|
701
|
+
};
|
|
702
|
+
|
|
703
|
+
return config;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
Server.serve({
|
|
708
|
+
plugins: [new DatabaseConfigPlugin()],
|
|
709
|
+
// ... other config
|
|
710
|
+
});
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
### Environment-Specific Overrides
|
|
714
|
+
|
|
715
|
+
```javascript
|
|
716
|
+
Server.serve({
|
|
717
|
+
// Base config
|
|
718
|
+
port: 8080,
|
|
719
|
+
|
|
720
|
+
// Environment overrides
|
|
721
|
+
[process.env.NODE_ENV]: {
|
|
722
|
+
port: process.env.NODE_ENV === 'production' ? 80 : 3000,
|
|
723
|
+
debug: process.env.NODE_ENV !== 'production'
|
|
724
|
+
}
|
|
725
|
+
});
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
## Best Practices
|
|
729
|
+
|
|
730
|
+
### Configuration Organization
|
|
731
|
+
|
|
732
|
+
1. **Separate concerns:** Keep different types of configuration in separate files
|
|
733
|
+
2. **Use environment variables:** For secrets and environment-specific values
|
|
734
|
+
3. **Validate early:** Use configuration validation to catch errors early
|
|
735
|
+
4. **Document overrides:** Comment which values can be overridden where
|
|
736
|
+
5. **Version control:** Keep configuration examples in version control
|
|
737
|
+
|
|
738
|
+
### Security
|
|
739
|
+
|
|
740
|
+
1. **Never commit secrets:** Use environment variables for sensitive data
|
|
741
|
+
2. **Validate inputs:** Always validate configuration values
|
|
742
|
+
3. **Principle of least privilege:** Use restrictive defaults
|
|
743
|
+
4. **Audit logging:** Log configuration changes in production
|
|
744
|
+
|
|
745
|
+
### Maintainability
|
|
746
|
+
|
|
747
|
+
1. **Consistent naming:** Use consistent naming conventions
|
|
748
|
+
2. **Documentation:** Document all configuration options
|
|
749
|
+
3. **Defaults:** Provide sensible defaults for all options
|
|
750
|
+
4. **Migration path:** Plan for configuration changes
|
|
751
|
+
|
|
752
|
+
### Performance
|
|
753
|
+
|
|
754
|
+
1. **Lazy loading:** Load configuration only when needed
|
|
755
|
+
2. **Caching:** Cache resolved configuration values
|
|
756
|
+
3. **Validation:** Validate configuration once at startup
|
|
757
|
+
4. **Monitoring:** Monitor configuration-related performance
|
|
758
|
+
|
|
759
|
+
## Troubleshooting Configuration
|
|
760
|
+
|
|
761
|
+
### Configuration Not Loading
|
|
762
|
+
|
|
763
|
+
**Check file existence:**
|
|
764
|
+
```bash
|
|
765
|
+
ls -la jsgui.config.js
|
|
766
|
+
```
|
|
767
|
+
|
|
768
|
+
**Verify syntax:**
|
|
769
|
+
```bash
|
|
770
|
+
node -c jsgui.config.js
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
**Check exports:**
|
|
774
|
+
```javascript
|
|
775
|
+
console.log(require('./jsgui.config.js')); // Should show object
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
### Environment Variables Ignored
|
|
779
|
+
|
|
780
|
+
**Check variable setting:**
|
|
781
|
+
```bash
|
|
782
|
+
echo $PORT
|
|
783
|
+
env | grep JSGUI
|
|
784
|
+
```
|
|
785
|
+
|
|
786
|
+
**Verify precedence:**
|
|
787
|
+
- CLI options override environment variables
|
|
788
|
+
- Environment variables override configuration files
|
|
789
|
+
- Configuration files override defaults
|
|
790
|
+
|
|
791
|
+
### Type Errors
|
|
792
|
+
|
|
793
|
+
**Common type issues:**
|
|
794
|
+
- Port as string: `"3000"` → `3000`
|
|
795
|
+
- Debug as string: `"true"` → `true`
|
|
796
|
+
- Paths as relative: `"./file"` → `require.resolve('./file')`
|
|
797
|
+
|
|
798
|
+
### Validation Errors
|
|
799
|
+
|
|
800
|
+
**Read error messages carefully:**
|
|
801
|
+
```
|
|
802
|
+
Error: Invalid configuration: port must be a number
|
|
803
|
+
Solution: port: 3000 instead of port: "3000"
|
|
804
|
+
```
|
|
805
|
+
|
|
806
|
+
---
|
|
807
|
+
|
|
808
|
+
This configuration reference provides comprehensive coverage of all JSGUI3 Server configuration options. Remember that most options have sensible defaults, so you only need to specify what differs from the defaults for your use case.
|