jsgui3-server 0.0.149 → 0.0.151

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/.github/agents/Mobile Developer.agent.md +89 -0
  2. package/.github/instructions/copilot.instructions.md +1 -0
  3. package/AGENTS.md +6 -0
  4. package/README.md +185 -0
  5. package/admin-ui/client.js +73 -43
  6. package/admin-ui/v1/admin_auth_service.js +197 -0
  7. package/admin-ui/v1/admin_user_store.js +71 -0
  8. package/admin-ui/v1/client.js +17 -0
  9. package/admin-ui/v1/controls/admin_shell.js +1399 -0
  10. package/admin-ui/v1/controls/group_box.js +84 -0
  11. package/admin-ui/v1/controls/stat_card.js +125 -0
  12. package/admin-ui/v1/server.js +658 -0
  13. package/admin-ui/v1/utils/formatters.js +68 -0
  14. package/docs/admin-extension-guide.md +345 -0
  15. package/docs/api-reference.md +383 -303
  16. package/docs/books/adaptive-control-improvements/01-control-candidate-matrix.md +122 -0
  17. package/docs/books/adaptive-control-improvements/02-tier-1-layout-playbooks.md +207 -0
  18. package/docs/books/adaptive-control-improvements/03-tier-2-navigation-form-overlay.md +140 -0
  19. package/docs/books/adaptive-control-improvements/04-cross-cutting-platform-functionality.md +141 -0
  20. package/docs/books/adaptive-control-improvements/05-styling-theming-density-upgrades.md +114 -0
  21. package/docs/books/adaptive-control-improvements/06-testing-quality-gates.md +97 -0
  22. package/docs/books/adaptive-control-improvements/07-delivery-roadmap-and-ownership.md +137 -0
  23. package/docs/books/adaptive-control-improvements/08-appendix-tier1-acceptance-and-pr-templates.md +261 -0
  24. package/docs/books/adaptive-control-improvements/README.md +66 -0
  25. package/docs/books/admin-ui-authentication/01-threat-model-and-goals.md +124 -0
  26. package/docs/books/admin-ui-authentication/02-session-model-and-token-model.md +75 -0
  27. package/docs/books/admin-ui-authentication/03-auth-middleware-patterns.md +77 -0
  28. package/docs/books/admin-ui-authentication/README.md +25 -0
  29. package/docs/books/creating-a-new-admin-ui/01-introduction-and-vision.md +130 -0
  30. package/docs/books/creating-a-new-admin-ui/02-architecture-and-data-flow.md +298 -0
  31. package/docs/books/creating-a-new-admin-ui/03-server-introspection.md +381 -0
  32. package/docs/books/creating-a-new-admin-ui/04-admin-module-adapter-layer.md +592 -0
  33. package/docs/books/creating-a-new-admin-ui/05-domain-controls-stat-cards-and-gauges.md +513 -0
  34. package/docs/books/creating-a-new-admin-ui/06-domain-controls-process-manager.md +544 -0
  35. package/docs/books/creating-a-new-admin-ui/07-domain-controls-resource-pool-inspector.md +493 -0
  36. package/docs/books/creating-a-new-admin-ui/08-domain-controls-route-table-and-api-explorer.md +586 -0
  37. package/docs/books/creating-a-new-admin-ui/09-domain-controls-log-viewer-and-activity-feed.md +490 -0
  38. package/docs/books/creating-a-new-admin-ui/10-domain-controls-build-status-and-bundle-inspector.md +526 -0
  39. package/docs/books/creating-a-new-admin-ui/11-domain-controls-configuration-panel.md +808 -0
  40. package/docs/books/creating-a-new-admin-ui/12-admin-shell-layout-sidebar-navigation.md +210 -0
  41. package/docs/books/creating-a-new-admin-ui/13-telemetry-integration.md +556 -0
  42. package/docs/books/creating-a-new-admin-ui/14-realtime-sse-observable-integration.md +485 -0
  43. package/docs/books/creating-a-new-admin-ui/15-styling-theming-aero-design-system.md +521 -0
  44. package/docs/books/creating-a-new-admin-ui/16-testing-and-quality-assurance.md +147 -0
  45. package/docs/books/creating-a-new-admin-ui/17-next-steps-process-resource-roadmap.md +356 -0
  46. package/docs/books/creating-a-new-admin-ui/README.md +68 -0
  47. package/docs/books/device-adaptive-composition/01-platform-feature-audit.md +177 -0
  48. package/docs/books/device-adaptive-composition/02-responsive-composition-model.md +187 -0
  49. package/docs/books/device-adaptive-composition/03-data-model-vs-view-model.md +231 -0
  50. package/docs/books/device-adaptive-composition/04-styling-theme-breakpoints.md +234 -0
  51. package/docs/books/device-adaptive-composition/05-showcase-app-multi-device-assessment.md +193 -0
  52. package/docs/books/device-adaptive-composition/06-implementation-patterns-and-apis.md +346 -0
  53. package/docs/books/device-adaptive-composition/07-testing-harness-and-quality-gates.md +265 -0
  54. package/docs/books/device-adaptive-composition/08-roadmap-and-adoption-plan.md +250 -0
  55. package/docs/books/device-adaptive-composition/README.md +47 -0
  56. package/docs/comparison-report-express-plex-cpanel.md +549 -0
  57. package/docs/comprehensive-documentation.md +220 -220
  58. package/docs/configuration-reference.md +227 -204
  59. package/docs/designs/server-admin-interface-aero.svg +611 -0
  60. package/docs/middleware-guide.md +236 -0
  61. package/docs/system-architecture.md +24 -18
  62. package/docs/troubleshooting.md +84 -53
  63. package/middleware/compression.js +217 -0
  64. package/middleware/index.js +15 -0
  65. package/module.js +19 -11
  66. package/package.json +1 -1
  67. package/serve-factory.js +29 -0
  68. package/server.js +280 -20
  69. package/tests/README.md +5 -0
  70. package/tests/admin-ui-jsgui-controls.test.js +581 -0
  71. package/tests/test-runner.js +1 -0
  72. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-071799b982906680f5fd699d.js +0 -40
  73. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-07352945ad5c92654fcb8b65.js +0 -39
  74. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-138a601fadb6191ea314c6fd.js +0 -39
  75. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-171f6c381c2cadf2e9fa7087.js +0 -39
  76. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-1d973388156b84a04373fac9.js +0 -39
  77. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-20e117bc8a10d2cd16234bbe.js +0 -40
  78. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-2b028a82b0e5efddba42425f.js +0 -39
  79. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-4518556cd5c7e059e82b22b8.js +0 -40
  80. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-5bac1aa0f213902f718ed74f.js +0 -40
  81. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-5f9996ac7822caf777d92f56.js +0 -39
  82. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-60a92c702e65fd9cf748e3ec.js +0 -39
  83. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-6164c1f8f738995c541895d2.js +0 -44
  84. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-6718a85eb9e5aa782dd47a05.js +0 -45
  85. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-69e280f14e37aee76a1d4675.js +0 -39
  86. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7570d1b030d44b111ed59c4c.js +0 -39
  87. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7798c9bbd55e510d5039f936.js +0 -42
  88. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-78cd511ea1ef18ecb03d1be5.js +0 -40
  89. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7d482e0b95bcb5e3c543118b.js +0 -43
  90. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-80e9476d1127c55b40fdb36f.js +0 -40
  91. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-810ced55d5320a3088a05b13.js +0 -40
  92. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-8423565f1a40e329afc8c6cf.js +0 -40
  93. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-900bef783b8cee36506ec282.js +0 -39
  94. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-a1a37aff6416fdad74040ddf.js +0 -39
  95. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-ad48d5e8eda40f175b4df090.js +0 -39
  96. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-aec5a2d963015528c9099462.js +0 -39
  97. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-af9d34e0f1722fab9e28c269.js +0 -39
  98. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-b818e4015e2f1fe86280b5ab.js +0 -41
  99. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-bcb2541adc70b7aba61768c5.js +0 -44
  100. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-bfe89d2c78ed44f95ed7dd73.js +0 -40
  101. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-c06f04806a1e688e1187110c.js +0 -40
  102. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-c3f3adf904f585afc544b96a.js +0 -39
  103. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-d45acb873e1d8e32d5e60f2e.js +0 -39
  104. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-db06f132533706f4a0163b8c.js +0 -39
  105. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-f660f40d78b135fc8560a862.js +0 -39
  106. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-f9dee4ec18a96e09bee06bae.js +0 -39
@@ -129,7 +129,7 @@ Configuration values are resolved in this order (later sources override earlier
129
129
  });
130
130
  ```
131
131
 
132
- ### API Configuration
132
+ ### API Configuration
133
133
 
134
134
  #### `api`
135
135
  - **Type:** `object`
@@ -154,81 +154,81 @@ Configuration values are resolved in this order (later sources override earlier
154
154
  'echo': (data) => data
155
155
  }
156
156
  });
157
- ```
158
-
159
- ### Resource and Event Options
160
-
161
- #### `resources`
162
- - **Type:** `object | array`
163
- - **Description:** Resource definitions to register in the server resource pool and start after server startup.
164
- - **Lifecycle:** Resources are started automatically after the HTTP server is listening and stopped automatically during `server.close()`.
165
- - **Supported forms:**
166
- - In-process resource instance
167
- - In-process resource constructor/class config
168
- - Process resource config (`type: 'process'` or inferred from `command`)
169
- - Remote process resource config (`type: 'remote'` or inferred from `host`/`endpoints`)
170
- - **Example:**
171
- ```javascript
172
- Server.serve({
173
- resources: {
174
- // In-process resource instance
175
- cache: new In_Process_Cache_Resource({ name: 'cache' }),
176
-
177
- // Process_Resource in direct mode (default)
178
- worker_direct: {
179
- type: 'process',
180
- command: process.execPath,
181
- args: ['worker.js'],
182
- autoRestart: true
183
- },
184
-
185
- // Process_Resource in PM2 mode (pm2Path optional)
186
- worker_pm2: {
187
- type: 'process',
188
- processManager: { type: 'pm2' },
189
- command: process.execPath,
190
- args: ['worker.js']
191
- },
192
-
193
- // Remote_Process_Resource
194
- remote_worker: {
195
- type: 'remote',
196
- host: '127.0.0.1',
197
- port: 3400,
198
- pollIntervalMs: 30000
199
- }
200
- }
201
- });
202
- ```
203
-
204
- **Process resource notes:**
205
- - `processManager` defaults to `direct`.
206
- - PM2 works without explicitly setting `pm2Path`:
207
- - `processManager.pm2Path` (if provided)
208
- - `PM2_PATH` env var (if provided)
209
- - local `node_modules/.bin/pm2` (if present)
210
- - `pm2` from `PATH`
211
-
212
- #### `events`
213
- - **Type:** `boolean | object`
214
- - **Description:** Enables a built-in SSE endpoint for resource lifecycle events.
215
- - **Default:** `false`
216
- - **When `true`:**
217
- - Registers `HTTP_SSE_Publisher` at `/events`
218
- - Forwards resource pool lifecycle events (`resource_state_change`, `crashed`, `unhealthy`, `unreachable`, `recovered`)
219
- - **When object:** Supports publisher options such as `route`, `name`, `keepaliveIntervalMs`, `maxClients`.
220
- - **Example:**
221
- ```javascript
222
- Server.serve({
223
- events: {
224
- route: '/events',
225
- keepaliveIntervalMs: 15000,
226
- maxClients: 200
227
- }
228
- });
229
- ```
230
-
231
- ### Static File Serving
157
+ ```
158
+
159
+ ### Resource and Event Options
160
+
161
+ #### `resources`
162
+ - **Type:** `object | array`
163
+ - **Description:** Resource definitions to register in the server resource pool and start after server startup.
164
+ - **Lifecycle:** Resources are started automatically after the HTTP server is listening and stopped automatically during `server.close()`.
165
+ - **Supported forms:**
166
+ - In-process resource instance
167
+ - In-process resource constructor/class config
168
+ - Process resource config (`type: 'process'` or inferred from `command`)
169
+ - Remote process resource config (`type: 'remote'` or inferred from `host`/`endpoints`)
170
+ - **Example:**
171
+ ```javascript
172
+ Server.serve({
173
+ resources: {
174
+ // In-process resource instance
175
+ cache: new In_Process_Cache_Resource({ name: 'cache' }),
176
+
177
+ // Process_Resource in direct mode (default)
178
+ worker_direct: {
179
+ type: 'process',
180
+ command: process.execPath,
181
+ args: ['worker.js'],
182
+ autoRestart: true
183
+ },
184
+
185
+ // Process_Resource in PM2 mode (pm2Path optional)
186
+ worker_pm2: {
187
+ type: 'process',
188
+ processManager: { type: 'pm2' },
189
+ command: process.execPath,
190
+ args: ['worker.js']
191
+ },
192
+
193
+ // Remote_Process_Resource
194
+ remote_worker: {
195
+ type: 'remote',
196
+ host: '127.0.0.1',
197
+ port: 3400,
198
+ pollIntervalMs: 30000
199
+ }
200
+ }
201
+ });
202
+ ```
203
+
204
+ **Process resource notes:**
205
+ - `processManager` defaults to `direct`.
206
+ - PM2 works without explicitly setting `pm2Path`:
207
+ - `processManager.pm2Path` (if provided)
208
+ - `PM2_PATH` env var (if provided)
209
+ - local `node_modules/.bin/pm2` (if present)
210
+ - `pm2` from `PATH`
211
+
212
+ #### `events`
213
+ - **Type:** `boolean | object`
214
+ - **Description:** Enables a built-in SSE endpoint for resource lifecycle events.
215
+ - **Default:** `false`
216
+ - **When `true`:**
217
+ - Registers `HTTP_SSE_Publisher` at `/events`
218
+ - Forwards resource pool lifecycle events (`resource_state_change`, `crashed`, `unhealthy`, `unreachable`, `recovered`)
219
+ - **When object:** Supports publisher options such as `route`, `name`, `keepaliveIntervalMs`, `maxClients`.
220
+ - **Example:**
221
+ ```javascript
222
+ Server.serve({
223
+ events: {
224
+ route: '/events',
225
+ keepaliveIntervalMs: 15000,
226
+ maxClients: 200
227
+ }
228
+ });
229
+ ```
230
+
231
+ ### Static File Serving
232
232
 
233
233
  #### `static`
234
234
  - **Type:** `object`
@@ -270,51 +270,51 @@ Configuration values are resolved in this order (later sources override earlier
270
270
  });
271
271
  ```
272
272
 
273
- #### `config`
274
- - **Type:** `string`
275
- - **Description:** Path to configuration file
276
- - **Default:** `'jsgui.config.js'` (if exists)
277
- - **Example:**
278
- ```javascript
279
- Server.serve({
280
- config: './my-config.js'
281
- });
282
- ```
283
-
284
- #### `style`
285
- - **Type:** `object`
286
- - **Description:** Style pipeline options for CSS/SCSS/Sass extraction and compilation.
287
- - **Default:** `{}` (inherits debug behavior for sourcemaps)
288
- - **Example:**
289
- ```javascript
290
- Server.serve({
291
- ctrl: MyControl,
292
- debug: true,
293
- style: {
294
- sourcemaps: {
295
- enabled: true,
296
- inline: true,
297
- include_sources: true
298
- },
299
- load_paths: ['styles', 'controls'],
300
- output_style: 'expanded',
301
- quiet_dependencies: true,
302
- compile_css_with_sass: true
303
- }
304
- });
305
- ```
306
-
307
- **Style options:**
308
- - `sourcemaps.enabled` (`boolean`): Enable CSS sourcemaps. Defaults to `true` when `debug` is enabled.
309
- - `sourcemaps.inline` (`boolean`): Inline sourcemaps into compiled CSS (default `true`).
310
- - `sourcemaps.include_sources` (`boolean`): Embed sources content in the sourcemap (default `true`).
311
- - `load_paths` (`string[]`): Sass load paths for `@use`/`@import`.
312
- - `output_style` (`string`): Sass output style (e.g., `expanded`, `compressed`).
313
- - `quiet_dependencies` (`boolean`): Suppress dependency warnings during Sass compilation.
314
- - `compile_css_with_sass` (`boolean`): Compile `.css` blocks through Sass when mixing with SCSS (default `true`).
315
- - `scss_sources` / `sass_sources` (`string[]`): Extra Sass/SCSS sources appended during compilation.
316
-
317
- Inline CSS sourcemaps are emitted only when a single compilation pass is possible. Mixed `.sass` plus `.scss`/`.css` inputs skip inline maps to avoid inaccurate mappings.
273
+ #### `config`
274
+ - **Type:** `string`
275
+ - **Description:** Path to configuration file
276
+ - **Default:** `'jsgui.config.js'` (if exists)
277
+ - **Example:**
278
+ ```javascript
279
+ Server.serve({
280
+ config: './my-config.js'
281
+ });
282
+ ```
283
+
284
+ #### `style`
285
+ - **Type:** `object`
286
+ - **Description:** Style pipeline options for CSS/SCSS/Sass extraction and compilation.
287
+ - **Default:** `{}` (inherits debug behavior for sourcemaps)
288
+ - **Example:**
289
+ ```javascript
290
+ Server.serve({
291
+ ctrl: MyControl,
292
+ debug: true,
293
+ style: {
294
+ sourcemaps: {
295
+ enabled: true,
296
+ inline: true,
297
+ include_sources: true
298
+ },
299
+ load_paths: ['styles', 'controls'],
300
+ output_style: 'expanded',
301
+ quiet_dependencies: true,
302
+ compile_css_with_sass: true
303
+ }
304
+ });
305
+ ```
306
+
307
+ **Style options:**
308
+ - `sourcemaps.enabled` (`boolean`): Enable CSS sourcemaps. Defaults to `true` when `debug` is enabled.
309
+ - `sourcemaps.inline` (`boolean`): Inline sourcemaps into compiled CSS (default `true`).
310
+ - `sourcemaps.include_sources` (`boolean`): Embed sources content in the sourcemap (default `true`).
311
+ - `load_paths` (`string[]`): Sass load paths for `@use`/`@import`.
312
+ - `output_style` (`string`): Sass output style (e.g., `expanded`, `compressed`).
313
+ - `quiet_dependencies` (`boolean`): Suppress dependency warnings during Sass compilation.
314
+ - `compile_css_with_sass` (`boolean`): Compile `.css` blocks through Sass when mixing with SCSS (default `true`).
315
+ - `scss_sources` / `sass_sources` (`string[]`): Extra Sass/SCSS sources appended during compilation.
316
+
317
+ Inline CSS sourcemaps are emitted only when a single compilation pass is possible. Mixed `.sass` plus `.scss`/`.css` inputs skip inline maps to avoid inaccurate mappings.
318
318
 
319
319
  ## Environment Variables
320
320
 
@@ -421,81 +421,81 @@ Server.serve({
421
421
  });
422
422
  ```
423
423
 
424
- ### Resource Pools
425
-
426
- ```javascript
427
- let server;
428
- server = await Server.serve({
429
- resources: {
430
- cache: new In_Process_Cache_Resource({
431
- name: 'cache'
432
- }),
433
- worker_direct: {
434
- type: 'process',
435
- command: process.execPath,
436
- args: ['worker.js']
437
- },
438
- remote_worker: {
439
- type: 'remote',
440
- host: '127.0.0.1',
441
- port: 3400
442
- }
443
- },
444
- events: true,
445
- api: {
446
- 'resources/summary': () => server.resource_pool.summary,
447
- 'resources/restart': async ({ name }) => {
448
- const resource = server.resource_pool.get_resource(name);
449
- if (!resource || typeof resource.restart !== 'function') {
450
- return { ok: false, error: 'Resource restart not supported' };
451
- }
452
- await resource.restart();
453
- return { ok: true, status: resource.status };
454
- }
455
- }
456
- });
457
- ```
458
-
459
- For strongly typed in-process resources you can also provide constructor-based entries:
460
-
461
- ```javascript
462
- Server.serve({
463
- resources: {
464
- in_process_metrics: {
465
- type: 'resource',
466
- class: In_Process_Metrics_Resource,
467
- spec: {
468
- sampleIntervalMs: 1000
469
- }
470
- },
471
- in_process_events: {
472
- constructor_fn: In_Process_Event_Bus_Resource,
473
- spec: {
474
- maxHistory: 500
475
- }
476
- },
477
- in_process_cache: {
478
- resource: new In_Process_Cache_Resource({
479
- name: 'in_process_cache'
480
- })
481
- },
482
- in_process_singleton: new In_Process_Registry_Resource({
483
- name: 'in_process_singleton'
484
- })
485
- }
486
- });
487
- ```
488
-
489
- ### Middleware
424
+ ### Resource Pools
490
425
 
491
426
  ```javascript
492
- const express = require('express');
493
- const compression = require('compression');
427
+ let server;
428
+ server = await Server.serve({
429
+ resources: {
430
+ cache: new In_Process_Cache_Resource({
431
+ name: 'cache'
432
+ }),
433
+ worker_direct: {
434
+ type: 'process',
435
+ command: process.execPath,
436
+ args: ['worker.js']
437
+ },
438
+ remote_worker: {
439
+ type: 'remote',
440
+ host: '127.0.0.1',
441
+ port: 3400
442
+ }
443
+ },
444
+ events: true,
445
+ api: {
446
+ 'resources/summary': () => server.resource_pool.summary,
447
+ 'resources/restart': async ({ name }) => {
448
+ const resource = server.resource_pool.get_resource(name);
449
+ if (!resource || typeof resource.restart !== 'function') {
450
+ return { ok: false, error: 'Resource restart not supported' };
451
+ }
452
+ await resource.restart();
453
+ return { ok: true, status: resource.status };
454
+ }
455
+ }
456
+ });
457
+ ```
458
+
459
+ For strongly typed in-process resources you can also provide constructor-based entries:
460
+
461
+ ```javascript
462
+ Server.serve({
463
+ resources: {
464
+ in_process_metrics: {
465
+ type: 'resource',
466
+ class: In_Process_Metrics_Resource,
467
+ spec: {
468
+ sampleIntervalMs: 1000
469
+ }
470
+ },
471
+ in_process_events: {
472
+ constructor_fn: In_Process_Event_Bus_Resource,
473
+ spec: {
474
+ maxHistory: 500
475
+ }
476
+ },
477
+ in_process_cache: {
478
+ resource: new In_Process_Cache_Resource({
479
+ name: 'in_process_cache'
480
+ })
481
+ },
482
+ in_process_singleton: new In_Process_Registry_Resource({
483
+ name: 'in_process_singleton'
484
+ })
485
+ }
486
+ });
487
+ ```
488
+
489
+ ### `middleware`
490
+ - **Type:** `Function | Function[]`
491
+ - **Description:** One or more Express-style middleware functions `(req, res, next)` to run before every request reaches the router. Middleware is executed in array order.
492
+
493
+ ```javascript
494
+ const { compression } = require('jsgui3-server/middleware');
494
495
 
495
496
  Server.serve({
496
497
  middleware: [
497
- compression(),
498
- express.json({ limit: '10mb' }),
498
+ compression({ threshold: 512 }),
499
499
  (req, res, next) => {
500
500
  console.log(`${req.method} ${req.url}`);
501
501
  next();
@@ -504,6 +504,29 @@ Server.serve({
504
504
  });
505
505
  ```
506
506
 
507
+ ### `compression`
508
+ - **Type:** `boolean | Object`
509
+ - **Description:** Convenience shorthand that enables the built-in response-compression middleware. Pass `true` for defaults or an options object.
510
+ - **Default:** Disabled (no compression)
511
+
512
+ | Sub-option | Type | Default | Description |
513
+ |------------|--------|---------------------------|--------------------------------------------|
514
+ | `threshold` | number | `1024` | Minimum body size (bytes) to compress |
515
+ | `level` | number | `Z_DEFAULT_COMPRESSION` | zlib compression level (1–9, or -1 for default) |
516
+
517
+ ```javascript
518
+ // Enable with defaults (1024 byte threshold, gzip preferred)
519
+ Server.serve({ compression: true });
520
+
521
+ // Enable with custom options
522
+ Server.serve({ compression: { threshold: 256, level: 6 } });
523
+ ```
524
+
525
+ > **Note:** `compression` and `middleware` can be used together. The `middleware` array runs first (in order), then the compression middleware is appended.
526
+
527
+ See [Middleware Guide](middleware-guide.md) for the full API, response-wrapping patterns, and custom middleware examples.
528
+ ```
529
+
507
530
  ## Configuration Validation
508
531
 
509
532
  ### Type Checking
@@ -523,18 +546,18 @@ Server.serve({ port: 'not-a-number' });
523
546
  - **Required:** None (auto-discovery provides defaults)
524
547
  - **Optional:** All options have sensible defaults
525
548
 
526
- ### Validation Rules
527
-
528
- - `port`: Must be number between 1-65535 or 0 (ephemeral)
529
- - `host`: Must be valid IPv4 address or hostname
530
- - `debug`: Converted to boolean using truthy() function
531
- - `pages`: Each page must have `content` property
532
- - `api`: Values must be functions
533
- - `static`: Values must be strings (directory paths)
534
- - `resources`: Must be an object map or array of supported resource entries
535
- - `resources.<name>.type`: Supported values include `process`, `remote`, `resource`, `in_process`, `in-process`
536
- - `resources.<name>.processManager.type`: Supported values include `direct`, `pm2`
537
- - `events`: Must be boolean or object
549
+ ### Validation Rules
550
+
551
+ - `port`: Must be number between 1-65535 or 0 (ephemeral)
552
+ - `host`: Must be valid IPv4 address or hostname
553
+ - `debug`: Converted to boolean using truthy() function
554
+ - `pages`: Each page must have `content` property
555
+ - `api`: Values must be functions
556
+ - `static`: Values must be strings (directory paths)
557
+ - `resources`: Must be an object map or array of supported resource entries
558
+ - `resources.<name>.type`: Supported values include `process`, `remote`, `resource`, `in_process`, `in-process`
559
+ - `resources.<name>.processManager.type`: Supported values include `direct`, `pm2`
560
+ - `events`: Must be boolean or object
538
561
 
539
562
  ## Configuration Patterns
540
563
 
@@ -965,4 +988,4 @@ Solution: port: 3000 instead of port: "3000"
965
988
 
966
989
  ---
967
990
 
968
- 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.
991
+ 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.