jsgui3-server 0.0.148 → 0.0.150

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 (154) hide show
  1. package/.github/agents/Mobile Developer.agent.md +89 -0
  2. package/.github/workflows/control-scan-manifest-check.yml +31 -0
  3. package/AGENTS.md +4 -0
  4. package/README.md +215 -3
  5. package/admin-ui/client.js +81 -51
  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/dev-status.svg +139 -0
  15. package/docs/admin-extension-guide.md +345 -0
  16. package/docs/api-reference.md +301 -43
  17. package/docs/books/adaptive-control-improvements/01-control-candidate-matrix.md +122 -0
  18. package/docs/books/adaptive-control-improvements/02-tier-1-layout-playbooks.md +207 -0
  19. package/docs/books/adaptive-control-improvements/03-tier-2-navigation-form-overlay.md +140 -0
  20. package/docs/books/adaptive-control-improvements/04-cross-cutting-platform-functionality.md +141 -0
  21. package/docs/books/adaptive-control-improvements/05-styling-theming-density-upgrades.md +114 -0
  22. package/docs/books/adaptive-control-improvements/06-testing-quality-gates.md +97 -0
  23. package/docs/books/adaptive-control-improvements/07-delivery-roadmap-and-ownership.md +137 -0
  24. package/docs/books/adaptive-control-improvements/08-appendix-tier1-acceptance-and-pr-templates.md +261 -0
  25. package/docs/books/adaptive-control-improvements/README.md +66 -0
  26. package/docs/books/admin-ui-authentication/01-threat-model-and-goals.md +124 -0
  27. package/docs/books/admin-ui-authentication/02-session-model-and-token-model.md +75 -0
  28. package/docs/books/admin-ui-authentication/03-auth-middleware-patterns.md +77 -0
  29. package/docs/books/admin-ui-authentication/README.md +25 -0
  30. package/docs/books/creating-a-new-admin-ui/01-introduction-and-vision.md +130 -0
  31. package/docs/books/creating-a-new-admin-ui/02-architecture-and-data-flow.md +298 -0
  32. package/docs/books/creating-a-new-admin-ui/03-server-introspection.md +381 -0
  33. package/docs/books/creating-a-new-admin-ui/04-admin-module-adapter-layer.md +592 -0
  34. package/docs/books/creating-a-new-admin-ui/05-domain-controls-stat-cards-and-gauges.md +513 -0
  35. package/docs/books/creating-a-new-admin-ui/06-domain-controls-process-manager.md +544 -0
  36. package/docs/books/creating-a-new-admin-ui/07-domain-controls-resource-pool-inspector.md +493 -0
  37. package/docs/books/creating-a-new-admin-ui/08-domain-controls-route-table-and-api-explorer.md +586 -0
  38. package/docs/books/creating-a-new-admin-ui/09-domain-controls-log-viewer-and-activity-feed.md +490 -0
  39. package/docs/books/creating-a-new-admin-ui/10-domain-controls-build-status-and-bundle-inspector.md +526 -0
  40. package/docs/books/creating-a-new-admin-ui/11-domain-controls-configuration-panel.md +808 -0
  41. package/docs/books/creating-a-new-admin-ui/12-admin-shell-layout-sidebar-navigation.md +210 -0
  42. package/docs/books/creating-a-new-admin-ui/13-telemetry-integration.md +556 -0
  43. package/docs/books/creating-a-new-admin-ui/14-realtime-sse-observable-integration.md +485 -0
  44. package/docs/books/creating-a-new-admin-ui/15-styling-theming-aero-design-system.md +521 -0
  45. package/docs/books/creating-a-new-admin-ui/16-testing-and-quality-assurance.md +147 -0
  46. package/docs/books/creating-a-new-admin-ui/17-next-steps-process-resource-roadmap.md +356 -0
  47. package/docs/books/creating-a-new-admin-ui/README.md +68 -0
  48. package/docs/books/device-adaptive-composition/01-platform-feature-audit.md +177 -0
  49. package/docs/books/device-adaptive-composition/02-responsive-composition-model.md +187 -0
  50. package/docs/books/device-adaptive-composition/03-data-model-vs-view-model.md +231 -0
  51. package/docs/books/device-adaptive-composition/04-styling-theme-breakpoints.md +234 -0
  52. package/docs/books/device-adaptive-composition/05-showcase-app-multi-device-assessment.md +193 -0
  53. package/docs/books/device-adaptive-composition/06-implementation-patterns-and-apis.md +346 -0
  54. package/docs/books/device-adaptive-composition/07-testing-harness-and-quality-gates.md +265 -0
  55. package/docs/books/device-adaptive-composition/08-roadmap-and-adoption-plan.md +250 -0
  56. package/docs/books/device-adaptive-composition/README.md +47 -0
  57. package/docs/books/jsgui3-bundling-research-book/00-table-of-contents.md +35 -0
  58. package/docs/books/jsgui3-bundling-research-book/01-pipeline-and-runtime-semantics.md +34 -0
  59. package/docs/books/jsgui3-bundling-research-book/02-javascript-bundling-core.md +36 -0
  60. package/docs/books/jsgui3-bundling-research-book/03-style-extraction-and-css-compilation.md +35 -0
  61. package/docs/books/jsgui3-bundling-research-book/04-static-publishing-and-delivery.md +39 -0
  62. package/docs/books/jsgui3-bundling-research-book/05-current-limits-and-size-bloat-vectors.md +25 -0
  63. package/docs/books/jsgui3-bundling-research-book/06-unused-module-elimination-strategy.md +77 -0
  64. package/docs/books/jsgui3-bundling-research-book/07-jsgui3-html-control-and-mixin-pruning.md +63 -0
  65. package/docs/books/jsgui3-bundling-research-book/08-test-and-verification-methodology.md +43 -0
  66. package/docs/books/jsgui3-bundling-research-book/09-roadmap-and-rollout.md +42 -0
  67. package/docs/books/jsgui3-bundling-research-book/10-further-research-strategies-and-upgrades.md +211 -0
  68. package/docs/books/jsgui3-bundling-research-book/README.md +35 -0
  69. package/docs/bundling-system-deep-dive.md +9 -4
  70. package/docs/comparison-report-express-plex-cpanel.md +549 -0
  71. package/docs/comprehensive-documentation.md +49 -18
  72. package/docs/configuration-reference.md +152 -27
  73. package/docs/core/README.md +19 -0
  74. package/docs/core/jsgui3-server-core-book/00-table-of-contents.md +21 -0
  75. package/docs/core/jsgui3-server-core-book/01-startup-readiness-state-machine.md +41 -0
  76. package/docs/core/jsgui3-server-core-book/02-resource-abstraction-and-lifecycle.md +92 -0
  77. package/docs/core/jsgui3-server-core-book/03-resource-pool-and-event-topology.md +47 -0
  78. package/docs/core/jsgui3-server-core-book/04-sse-publisher-semantics.md +41 -0
  79. package/docs/core/jsgui3-server-core-book/05-serve-factory-resource-wiring.md +46 -0
  80. package/docs/core/jsgui3-server-core-book/06-e2e-testing-methodology.md +48 -0
  81. package/docs/core/jsgui3-server-core-book/07-defect-detection-and-hardening-loop.md +47 -0
  82. package/docs/designs/server-admin-interface-aero.svg +611 -0
  83. package/docs/publishers-guide.md +59 -4
  84. package/docs/resources-guide.md +184 -35
  85. package/docs/simple-server-api-design.md +72 -17
  86. package/docs/system-architecture.md +18 -14
  87. package/docs/troubleshooting.md +84 -53
  88. package/examples/controls/15) window, observable SSE/server.js +6 -1
  89. package/examples/controls/19) window, auto observable ui/server.js +9 -0
  90. package/examples/controls/20) window, task manager app/README.md +133 -0
  91. package/examples/controls/20) window, task manager app/client.js +797 -0
  92. package/examples/controls/20) window, task manager app/server.js +178 -0
  93. package/examples/controls/6) window, color_palette/client.js +165 -68
  94. package/examples/controls/9) window, date picker/client.js +362 -76
  95. package/examples/controls/9b) window, shared data.model mirrored date pickers/client.js +104 -83
  96. package/examples/jsgui3-html/06) theming/client.js +22 -1
  97. package/examples/jsgui3-html/10) binding-debugger/client.js +137 -1
  98. package/http/responders/static/Static_Route_HTTP_Responder.js +52 -34
  99. package/lab/experiments/capture-color-controls.js +196 -0
  100. package/lab/results/screenshots/color-controls/full_page.png +0 -0
  101. package/lab/results/screenshots/color-controls/section_1_color_grid_12x12.png +0 -0
  102. package/lab/results/screenshots/color-controls/section_2_color_grid_4x2.png +0 -0
  103. package/lab/results/screenshots/color-controls/section_3_color_palette.png +0 -0
  104. package/lab/results/screenshots/color-controls/section_4_palette_comparison.png +0 -0
  105. package/lab/results/screenshots/color-controls/section_5_raw_swatches.png +0 -0
  106. package/lab/results/screenshots/color-controls/section_6_optimized_crayola.png +0 -0
  107. package/lab/results/screenshots/color-controls/section_7_pastel_palette.png +0 -0
  108. package/lab/results/screenshots/color-controls/section_8_extended_144.png +0 -0
  109. package/lab/screenshot-utils.js +248 -0
  110. package/module.js +12 -0
  111. package/package.json +12 -2
  112. package/publishers/Publishers.js +4 -3
  113. package/publishers/helpers/assigners/static-compressed-response-buffers/Single_Control_Webpage_Server_Static_Compressed_Response_Buffers_Assigner.js +5 -5
  114. package/publishers/http-sse-publisher.js +341 -0
  115. package/resources/process-resource.js +950 -0
  116. package/resources/processors/bundlers/js/esbuild/Advanced_JS_Bundler_Using_ESBuild.js +129 -33
  117. package/resources/processors/bundlers/js/esbuild/Core_JS_Non_Minifying_Bundler_Using_ESBuild.js +18 -7
  118. package/resources/processors/bundlers/js/esbuild/JSGUI3_HTML_Control_Optimizer.js +829 -0
  119. package/resources/remote-process-resource.js +355 -0
  120. package/resources/server-resource-pool.js +354 -41
  121. package/serve-factory.js +442 -259
  122. package/server.js +288 -13
  123. package/tests/README.md +71 -4
  124. package/tests/admin-ui-jsgui-controls.test.js +581 -0
  125. package/tests/admin-ui-render.test.js +24 -0
  126. package/tests/assigners.test.js +56 -40
  127. package/tests/bundling-default-control-elimination.puppeteer.test.js +260 -0
  128. package/tests/configuration-validation.test.js +21 -18
  129. package/tests/content-analysis.test.js +7 -6
  130. package/tests/control-optimizer-cache-behavior.test.js +52 -0
  131. package/tests/control-scan-manifest-regression.test.js +144 -0
  132. package/tests/end-to-end.test.js +15 -14
  133. package/tests/error-handling.test.js +222 -179
  134. package/tests/fixtures/bundling-default-button-client.js +37 -0
  135. package/tests/fixtures/bundling-default-window-client.js +34 -0
  136. package/tests/fixtures/control_scan_manifest_expectations.json +48 -0
  137. package/tests/fixtures/resource-monitor-client.js +319 -0
  138. package/tests/helpers/puppeteer-e2e-harness.js +317 -0
  139. package/tests/http-sse-publisher.test.js +136 -0
  140. package/tests/performance.test.js +69 -65
  141. package/tests/process-resource.test.js +138 -0
  142. package/tests/publishers.test.js +7 -7
  143. package/tests/remote-process-resource.test.js +160 -0
  144. package/tests/sass-controls.e2e.test.js +7 -1
  145. package/tests/serve-resources.test.js +270 -0
  146. package/tests/serve.test.js +120 -50
  147. package/tests/server-resource-pool.test.js +106 -0
  148. package/tests/small-controls-bundle-size.test.js +252 -0
  149. package/tests/test-runner.js +14 -1
  150. package/tests/window-examples.puppeteer.test.js +204 -1
  151. package/tests/window-resource-integration.puppeteer.test.js +585 -0
  152. package/tests/temp_invalid.js +0 -7
  153. package/tests/temp_invalid_utf8.js +0 -1
  154. package/tests/temp_malformed.js +0 -10
@@ -100,7 +100,7 @@ const publisher = new HTTP_Function_Publisher({
100
100
  - Support for common image formats (JPEG, PNG, SVG, etc.)
101
101
  - Efficient streaming for large files
102
102
 
103
- ### HTTP_Observable_Publisher
103
+ ### HTTP_Observable_Publisher
104
104
 
105
105
  **Purpose:** Streams observable data to clients using Server-Sent Events (SSE).
106
106
 
@@ -190,9 +190,64 @@ data: {"tick":1,"timestamp":1234567890,"message":"Server tick #1"}
190
190
  data: {"tick":2,"timestamp":1234567891,"message":"Server tick #2"}
191
191
  ```
192
192
 
193
- **See Also:** [Observable SSE Demo](../examples/controls/15)%20window,%20observable%20SSE/) for a complete working example.
194
-
195
- ## Publisher Architecture
193
+ **See Also:** [Observable SSE Demo](../examples/controls/15)%20window,%20observable%20SSE/) for a complete working example.
194
+
195
+ ### HTTP_SSE_Publisher
196
+
197
+ **Purpose:** General-purpose Server-Sent Events publisher for manual event fan-out (not tied to an observable source).
198
+
199
+ **Key Features:**
200
+ - SSE client connection registry with `client_count`
201
+ - `broadcast(event_name, data)` for fan-out to all clients
202
+ - `send(client_id, event_name, data)` for targeted delivery
203
+ - Keepalive comments (`:keepalive`) to prevent idle proxy timeouts
204
+ - Last-Event-ID replay support for reconnecting clients
205
+ - Optional max-client limit
206
+ - Emits:
207
+ - `client_connected`
208
+ - `client_disconnected`
209
+
210
+ **Usage:**
211
+ ```javascript
212
+ const HTTP_SSE_Publisher = require('jsgui3-server/publishers/http-sse-publisher');
213
+
214
+ const sse_publisher = new HTTP_SSE_Publisher({
215
+ name: 'events',
216
+ keepaliveIntervalMs: 15000,
217
+ maxClients: 100
218
+ });
219
+
220
+ server.server_router.set_route('/events', sse_publisher, sse_publisher.handle_http);
221
+
222
+ sse_publisher.broadcast('resource_state_change', {
223
+ resourceName: 'worker_1',
224
+ from: 'running',
225
+ to: 'crashed'
226
+ });
227
+ ```
228
+
229
+ **With `Server.serve()` Auto Wiring:**
230
+ ```javascript
231
+ const server = await Server.serve({
232
+ events: true,
233
+ resources: {
234
+ worker_1: {
235
+ type: 'process',
236
+ command: process.execPath,
237
+ args: ['worker.js']
238
+ }
239
+ }
240
+ });
241
+
242
+ // SSE endpoint is available at /events by default.
243
+ ```
244
+
245
+ ### Choosing an SSE Publisher
246
+
247
+ - Use `HTTP_Observable_Publisher` when your source is an observable stream.
248
+ - Use `HTTP_SSE_Publisher` when you need explicit event push control (`broadcast`/`send`) from arbitrary server logic.
249
+
250
+ ## Publisher Architecture
196
251
 
197
252
  ### Base Publisher Class
198
253
 
@@ -17,19 +17,26 @@ Resources are JSGUI3 Server's abstraction layer for accessing data, functionalit
17
17
 
18
18
  ## Resource Types
19
19
 
20
- ### Server_Resource_Pool
21
-
22
- **Purpose:** Manages collections of resources with access control and lifecycle management.
23
-
24
- **Key Features:**
25
- - Resource registration and discovery
26
- - Access control through permission systems
27
- - Lifecycle management (start/stop/cleanup)
28
- - Resource dependency resolution
29
-
30
- **Usage:**
31
- ```javascript
32
- const pool = new Server_Resource_Pool({
20
+ ### Server_Resource_Pool
21
+
22
+ **Purpose:** Manages collections of resources with access control and lifecycle management.
23
+
24
+ **Key Features:**
25
+ - Resource registration and discovery
26
+ - Access control through permission systems
27
+ - Lifecycle management (`start()`, `stop()`, `remove(name)`)
28
+ - Type filtering with `get_resources_by_type(type)`
29
+ - Aggregated `summary` view of resource states
30
+ - Resource event forwarding:
31
+ - `resource_state_change`
32
+ - `crashed`
33
+ - `unhealthy`
34
+ - `unreachable`
35
+ - `recovered`
36
+
37
+ **Usage:**
38
+ ```javascript
39
+ const pool = new Server_Resource_Pool({
33
40
  access: {
34
41
  full: ['admin'],
35
42
  read: ['user']
@@ -37,14 +44,117 @@ const pool = new Server_Resource_Pool({
37
44
  });
38
45
 
39
46
  pool.add(myResource);
40
- pool.start((err) => {
41
- // Pool is ready
42
- });
43
- ```
44
-
45
- ### Website_Resource
46
-
47
- **Purpose:** Wraps website objects for integration with the server's resource system.
47
+ pool.start((err) => {
48
+ // Pool is ready
49
+ });
50
+
51
+ const summary = pool.summary;
52
+ const process_resources = pool.get_resources_by_type('Process_Resource');
53
+ await pool.remove('legacy_worker');
54
+ ```
55
+
56
+ ### Process_Resource
57
+
58
+ **Purpose:** Represents a local long-running process as a resource.
59
+
60
+ **Key Features:**
61
+ - State machine lifecycle:
62
+ - `stopped`
63
+ - `starting`
64
+ - `running`
65
+ - `stopping`
66
+ - `restarting`
67
+ - `crashed`
68
+ - Emits:
69
+ - `state_change`
70
+ - `stdout`
71
+ - `stderr`
72
+ - `exit`
73
+ - `health_check`
74
+ - `unhealthy`
75
+ - `crashed`
76
+ - Auto-restart with exponential backoff (when `autoRestart: true`)
77
+ - Optional health checks (`http`, `tcp`, `custom`)
78
+ - Consistent status shape for direct and PM2-backed processes
79
+
80
+ **Process Manager Modes:**
81
+ - `direct` (default): Uses `child_process.spawn()`
82
+ - `pm2`: Uses PM2 CLI commands
83
+
84
+ **PM2 Path Resolution:**
85
+ - If `processManager.pm2Path` is set, it is used
86
+ - Else `PM2_PATH` env var is used (if set)
87
+ - Else local `node_modules/.bin/pm2` is used if present
88
+ - Else `pm2` is resolved from system `PATH`
89
+
90
+ **Usage:**
91
+ ```javascript
92
+ const Process_Resource = require('jsgui3-server/resources/process-resource');
93
+
94
+ // Direct mode (default)
95
+ const worker_direct = new Process_Resource({
96
+ name: 'worker_direct',
97
+ command: process.execPath,
98
+ args: ['worker.js'],
99
+ autoRestart: true
100
+ });
101
+
102
+ // PM2 mode (pm2Path optional)
103
+ const worker_pm2 = new Process_Resource({
104
+ name: 'worker_pm2',
105
+ processManager: { type: 'pm2' },
106
+ command: process.execPath,
107
+ args: ['worker.js']
108
+ });
109
+
110
+ await worker_direct.start();
111
+ console.log(worker_direct.status);
112
+ await worker_direct.stop();
113
+ ```
114
+
115
+ ### Remote_Process_Resource
116
+
117
+ **Purpose:** Represents a remote process controlled via HTTP API while keeping a resource-compatible interface.
118
+
119
+ **Key Features:**
120
+ - Same high-level lifecycle API as `Process_Resource`:
121
+ - `start()`
122
+ - `stop()`
123
+ - `restart()`
124
+ - `status`
125
+ - `get_abstract()`
126
+ - Periodic polling of remote status endpoint
127
+ - Emits:
128
+ - `state_change`
129
+ - `unreachable`
130
+ - `recovered`
131
+ - Maintains bounded history snapshots for diagnostics
132
+
133
+ **Usage:**
134
+ ```javascript
135
+ const Remote_Process_Resource = require('jsgui3-server/resources/remote-process-resource');
136
+
137
+ const remote_worker = new Remote_Process_Resource({
138
+ name: 'remote_worker',
139
+ host: '192.168.1.100',
140
+ port: 3400,
141
+ pollIntervalMs: 30000,
142
+ httpTimeoutMs: 6000,
143
+ endpoints: {
144
+ status: '/',
145
+ start: '/api/start',
146
+ stop: '/api/stop',
147
+ health: '/api/health'
148
+ }
149
+ });
150
+
151
+ await remote_worker.start();
152
+ console.log(remote_worker.status);
153
+ ```
154
+
155
+ ### Website_Resource
156
+
157
+ **Purpose:** Wraps website objects for integration with the server's resource system.
48
158
 
49
159
  **Key Features:**
50
160
  - Website object encapsulation
@@ -110,16 +220,34 @@ class Custom_Resource extends Resource {
110
220
  }
111
221
  ```
112
222
 
113
- ### Lifecycle Management
114
-
115
- Resources follow a consistent lifecycle:
223
+ ### Lifecycle Management
224
+
225
+ Resources follow a consistent lifecycle:
116
226
 
117
227
  1. **Construction**: Resource is instantiated with configuration
118
228
  2. **Registration**: Added to resource pool
119
229
  3. **Start**: Resource becomes active and available
120
230
  4. **Usage**: Resource handles requests and operations
121
231
  5. **Stop**: Resource is deactivated
122
- 6. **Cleanup**: Resources are released
232
+ 6. **Cleanup**: Resources are released
233
+
234
+ For process resources, consumers can rely on the same lifecycle API regardless of execution mode (`direct`, `pm2`, or `remote`).
235
+
236
+ ### Unified Process Status
237
+
238
+ Both `Process_Resource` and `Remote_Process_Resource` expose a compatible `status` shape:
239
+
240
+ ```javascript
241
+ {
242
+ state: 'running',
243
+ pid: 12345,
244
+ uptime: 61520,
245
+ restartCount: 1,
246
+ lastHealthCheck: null,
247
+ memoryUsage: { rssBytes: 104857600 },
248
+ processManager: { type: 'direct' } // or 'pm2' / 'remote'
249
+ }
250
+ ```
123
251
 
124
252
  ### Configuration Patterns
125
253
 
@@ -171,18 +299,39 @@ class Database_Resource extends Resource {
171
299
  }
172
300
  ```
173
301
 
174
- ### Integration with Server
175
-
176
- ```javascript
177
- // Add to resource pool
178
- server.resource_pool.add(databaseResource);
302
+ ### Integration with Server
303
+
304
+ ```javascript
305
+ // Add to resource pool
306
+ server.resource_pool.add(databaseResource);
179
307
 
180
308
  // Access from other components
181
309
  const db = server.resource_pool.get_resource('Database_Resource');
182
- db.query('SELECT * FROM users', [], (err, results) => {
183
- // Handle results
184
- });
185
- ```
310
+ db.query('SELECT * FROM users', [], (err, results) => {
311
+ // Handle results
312
+ });
313
+ ```
314
+
315
+ With `Server.serve()` you can register resources declaratively:
316
+
317
+ ```javascript
318
+ const server = await Server.serve({
319
+ resources: {
320
+ worker_direct: {
321
+ type: 'process',
322
+ command: process.execPath,
323
+ args: ['worker.js']
324
+ },
325
+ remote_worker: {
326
+ type: 'remote',
327
+ host: '127.0.0.1',
328
+ port: 3400
329
+ },
330
+ local_cache: new In_Process_Cache_Resource({ name: 'local_cache' })
331
+ },
332
+ events: true
333
+ });
334
+ ```
186
335
 
187
336
  ## Resource Communication Patterns
188
337
 
@@ -612,4 +761,4 @@ class Logged_Resource extends Resource {
612
761
 
613
762
  ---
614
763
 
615
- This guide provides the foundation for understanding and extending the resource system. For specific resource implementations, refer to their individual source files in the `resources/` directory.
764
+ This guide provides the foundation for understanding and extending the resource system. For specific resource implementations, refer to their individual source files in the `resources/` directory.
@@ -21,7 +21,7 @@ This document explains the design principles and implementation of the simplifie
21
21
  2. **Convention Over Configuration** – Smart defaults; minimal required config
22
22
  3. **Consistent Patterns** – Same API shape at every scale
23
23
  4. **Zero-to-Hero Path** – Clear upgrade path from simple to advanced
24
- 5. **Composable** – Mix and match features (pages, APIs, static files)
24
+ 5. **Composable** – Mix and match features (pages, APIs, static files, managed resources, SSE events)
25
25
 
26
26
  ---
27
27
 
@@ -218,7 +218,59 @@ Server.serve({
218
218
 
219
219
  ---
220
220
 
221
- ### Layer 5: Shorthand Routes (Mixed Types)
221
+ ### Layer 5: Managed Resources + Lifecycle Events
222
+
223
+ **Use Case:** Run and supervise background workers alongside your web app, with optional SSE event streaming.
224
+
225
+ ```javascript
226
+ let server;
227
+ server = await Server.serve({
228
+ page: {
229
+ content: DashboardControl,
230
+ title: 'Ops Dashboard'
231
+ },
232
+ resources: {
233
+ // In-process resource object
234
+ cache: new In_Process_Cache_Resource({ name: 'cache' }),
235
+
236
+ // Local process resource (default manager: direct)
237
+ worker_direct: {
238
+ type: 'process',
239
+ command: process.execPath,
240
+ args: ['worker.js'],
241
+ autoRestart: true
242
+ },
243
+
244
+ // PM2-backed local process (pm2Path optional)
245
+ worker_pm2: {
246
+ type: 'process',
247
+ processManager: { type: 'pm2' },
248
+ command: process.execPath,
249
+ args: ['worker.js']
250
+ },
251
+
252
+ // Remote HTTP-controlled process
253
+ remote_agent: {
254
+ type: 'remote',
255
+ host: '127.0.0.1',
256
+ port: 3400
257
+ }
258
+ },
259
+ events: true, // enables /events SSE endpoint
260
+ api: {
261
+ 'resources/summary': () => server.resource_pool.summary
262
+ }
263
+ });
264
+ ```
265
+
266
+ **Lifecycle conventions:**
267
+ - Process-like resources expose the same API shape: `start()`, `stop()`, `restart()`, `status`, `get_abstract()`
268
+ - Resource pool forwards lifecycle events (`resource_state_change`, `crashed`, `unhealthy`, `unreachable`, `recovered`)
269
+ - `server.close()` stops managed resources and SSE publisher cleanly
270
+
271
+ ---
272
+
273
+ ### Layer 6: Shorthand Routes (Mixed Types)
222
274
 
223
275
  **Use Case:** Mix controls, functions, and static content flexibly
224
276
 
@@ -242,7 +294,7 @@ Server.serve({
242
294
 
243
295
  ---
244
296
 
245
- ### Layer 6: Full Website Object
297
+ ### Layer 7: Full Website Object
246
298
 
247
299
  **Use Case:** Complex multi-page sites, existing `Website` instances
248
300
 
@@ -283,7 +335,7 @@ Server.serve({
283
335
 
284
336
  ---
285
337
 
286
- ### Layer 7: Legacy/Advanced (Current API)
338
+ ### Layer 8: Legacy/Advanced (Current API)
287
339
 
288
340
  **Still fully supported for maximum control:**
289
341
 
@@ -542,12 +594,14 @@ require('../../../server').serve(require('./client').controls.Demo_UI);
542
594
  - [x] Return a Promise that resolves with the server instance
543
595
  - [x] Support Promise/async and callback patterns
544
596
 
545
- ### Phase 2: API & Static (Partially Complete)
546
- - [x] `api` option for function publishing
547
- - [x] Auto-prefix `/api/` routes
548
- - [x] JSON/text content-type detection
549
- - [ ] `static` option for directory serving
550
- - [ ] MIME type detection for static files
597
+ ### Phase 2: API & Static (Partially Complete)
598
+ - [x] `api` option for function publishing
599
+ - [x] Auto-prefix `/api/` routes
600
+ - [x] JSON/text content-type detection
601
+ - [x] `resources` option for in-process/process/remote managed resources
602
+ - [x] `events` option for built-in SSE lifecycle publisher
603
+ - [ ] `static` option for directory serving
604
+ - [ ] MIME type detection for static files
551
605
 
552
606
  ### Phase 3: Enhanced Features (Partially Complete)
553
607
  - [x] ENV var support (PORT, HOST, JSGUI_DEBUG)
@@ -706,10 +760,11 @@ server.on('ready', () => {
706
760
  - Promise/async support
707
761
  - Still 100% backwards compatible
708
762
 
709
- ### Key Benefits
710
- 1. **Faster prototyping** – from idea to running in seconds
711
- 2. **Less boilerplate** – 90% reduction for simple cases
712
- 3. **Better defaults** – works out of the box
713
- 4. **Clearer intent** – code reads like configuration
714
- 5. **Easy scaling** – simple projects grow naturally
715
- 6. **Zero breaking changes** – all existing code still works
763
+ ### Key Benefits
764
+ 1. **Faster prototyping** – from idea to running in seconds
765
+ 2. **Less boilerplate** – 90% reduction for simple cases
766
+ 3. **Better defaults** – works out of the box
767
+ 4. **Clearer intent** – code reads like configuration
768
+ 5. **Easy scaling** – simple projects grow naturally
769
+ 6. **Zero breaking changes** – all existing code still works
770
+ 7. **Unified runtime operations** – consistent process/resource lifecycle APIs with optional SSE observability
@@ -32,25 +32,29 @@ JSGUI3 Server is a Node.js-based web framework that serves modern JavaScript GUI
32
32
 
33
33
  **Purpose:** Handles conversion of various content types to HTTP responses.
34
34
 
35
- **Key Publishers:**
36
- - `HTTP_Webpage_Publisher`: Serves bundled JSGUI3 controls as complete web pages
37
- - `HTTP_Website_Publisher`: Manages multi-page websites
38
- - `HTTP_Function_Publisher`: Exposes JavaScript functions as REST API endpoints
39
- - `HTTP_CSS_Publisher`: Serves CSS stylesheets
40
- - `HTTP_JS_Publisher`: Serves JavaScript bundles
41
- - `HTTP_Image_Publisher`: Handles image file serving
35
+ **Key Publishers:**
36
+ - `HTTP_Webpage_Publisher`: Serves bundled JSGUI3 controls as complete web pages
37
+ - `HTTP_Website_Publisher`: Manages multi-page websites
38
+ - `HTTP_Function_Publisher`: Exposes JavaScript functions as REST API endpoints
39
+ - `HTTP_Observable_Publisher`: Streams observable-backed SSE
40
+ - `HTTP_SSE_Publisher`: General-purpose SSE fan-out publisher
41
+ - `HTTP_CSS_Publisher`: Serves CSS stylesheets
42
+ - `HTTP_JS_Publisher`: Serves JavaScript bundles
43
+ - `HTTP_Image_Publisher`: Handles image file serving
42
44
 
43
45
  ### 3. Resource Management Layer
44
46
  **Directory:** `resources/`
45
47
 
46
48
  **Purpose:** Provides abstractions for accessing different types of data and functionality.
47
49
 
48
- **Key Resources:**
49
- - `Server_Resource_Pool`: Manages collections of resources with lifecycle management
50
- - `Website_Resource`: Wraps website objects for server integration
51
- - `File_System_Resource`: Provides file system access
52
- - `Data_Resource`: Handles data storage and retrieval
53
- - `Local_Server_Info_Resource`: Provides server environment information
50
+ **Key Resources:**
51
+ - `Server_Resource_Pool`: Manages collections of resources with lifecycle management
52
+ - `Process_Resource`: Local process resource (`direct` default, optional `pm2`)
53
+ - `Remote_Process_Resource`: HTTP-controlled remote process resource
54
+ - `Website_Resource`: Wraps website objects for server integration
55
+ - `File_System_Resource`: Provides file system access
56
+ - `Data_Resource`: Handles data storage and retrieval
57
+ - `Local_Server_Info_Resource`: Provides server environment information
54
58
 
55
59
  ### 4. Processing Layer
56
60
  **Directory:** `resources/processors/`
@@ -272,4 +276,4 @@ Add new processing pipelines for assets and data.
272
276
 
273
277
  ---
274
278
 
275
- This architecture document provides the foundation for understanding how JSGUI3 Server components work together. For detailed implementation of specific components, refer to their individual documentation files.
279
+ This architecture document provides the foundation for understanding how JSGUI3 Server components work together. For detailed implementation of specific components, refer to their individual documentation files.
@@ -197,14 +197,14 @@ input.js:1:0: ERROR: Expected identifier but found "}"
197
197
 
198
198
  2. **Verify CSS definition:**
199
199
  ```javascript
200
- MyControl.css = `
201
- .my-control {
202
- padding: 20px;
203
- background: #f0f0f0;
204
- }
205
- `;
206
- ```
207
- You can also use `MyControl.scss` or `MyControl.sass` with template literals; these compile to CSS during bundling (ensure the `sass` dependency is installed). To see inline CSS sourcemaps in devtools, enable `style.sourcemaps` (or run with `debug: true`).
200
+ MyControl.css = `
201
+ .my-control {
202
+ padding: 20px;
203
+ background: #f0f0f0;
204
+ }
205
+ `;
206
+ ```
207
+ You can also use `MyControl.scss` or `MyControl.sass` with template literals; these compile to CSS during bundling (ensure the `sass` dependency is installed). To see inline CSS sourcemaps in devtools, enable `style.sourcemaps` (or run with `debug: true`).
208
208
 
209
209
  3. **Check activation:**
210
210
  ```javascript
@@ -540,6 +540,37 @@ from origin 'http://localhost:3000' has been blocked by CORS policy
540
540
  delete require.cache[require.resolve('./client.js')];
541
541
  ```
542
542
 
543
+ ### Generated `.jsgui3-server-cache` Shim Files
544
+
545
+ **Symptoms:**
546
+ - You see many changed files under `.jsgui3-server-cache/jsgui3-html-shims/`
547
+ - Shim files contain absolute machine-specific paths
548
+ - Git status looks noisy after running examples or admin pages
549
+
550
+ **What this is:**
551
+ - These are generated cache artifacts created by the bundling/render pipeline.
552
+ - They are performance helpers, not source-of-truth project files.
553
+
554
+ **Expected behavior:**
555
+ 1. They may be regenerated when controls, environment, or module resolution changes.
556
+ 2. They can differ across machines (for example, local `node_modules` path vs NVM/global path).
557
+ 3. They are safe to delete; they will be recreated when needed.
558
+
559
+ **Recommended project hygiene:**
560
+ 1. Ignore cache directories in `.gitignore`:
561
+ ```gitignore
562
+ .jsgui3-server-cache/
563
+ **/.jsgui3-server-cache/
564
+ ```
565
+ 2. If accidentally changed, revert generated shims:
566
+ ```bash
567
+ git restore -- .jsgui3-server-cache/jsgui3-html-shims/*.js
568
+ ```
569
+ 3. If a nested example cache appears, remove it:
570
+ ```bash
571
+ rm -rf "examples/controls/1) window/.jsgui3-server-cache"
572
+ ```
573
+
543
574
  ### Source Maps Not Working
544
575
 
545
576
  **Symptoms:**
@@ -743,48 +774,48 @@ controls.MinimalControl = MinimalControl;
743
774
  module.exports = jsgui;
744
775
  ```
745
776
 
746
- This minimal setup helps isolate whether the issue is with your specific code or the framework itself.
747
-
748
- ---
749
-
750
- ## Bundling and Test Failures
751
-
752
- ### `waiting for wp_publisher ready` or Publisher Ready Timeout
753
-
754
- **Symptoms:**
755
- - Tests hang while starting servers
756
- - Logs show `waiting for wp_publisher ready`
757
- - Tests time out without a clear stack trace
758
-
759
- **Likely cause:** the JS/CSS bundler failed before emitting `ready`.
760
-
761
- **What to check:**
762
- 1. Look earlier in the log for bundler errors (esbuild, Sass, file resolution).
763
- 2. Confirm `sass` is installed if you are running Sass tests.
764
- 3. Validate the client entry path passed to `src_path_client_js`.
765
-
766
- ### esbuild platform mismatch (Windows vs WSL)
767
-
768
- **Symptoms:**
769
- - Error: `You installed esbuild for another platform than the one you're currently using`
770
-
771
- **Cause:** `node_modules` was installed on a different OS and reused in this environment.
772
-
773
- **Fix:**
774
- 1. Remove the existing `node_modules` from the current workspace.
775
- 2. Reinstall dependencies in the current environment:
776
- ```bash
777
- npm install
778
- ```
779
- 3. If you prefer to keep the lockfile untouched, use:
780
- ```bash
781
- npm ci
782
- ```
783
- 4. As a fast workaround, you can try:
784
- ```bash
785
- npm rebuild esbuild
786
- ```
787
-
788
- ---
789
-
790
- Remember: Most issues can be resolved by carefully checking the console output, verifying file paths, and ensuring proper control lifecycle management. Start with the basics and work systematically through the possible causes.
777
+ This minimal setup helps isolate whether the issue is with your specific code or the framework itself.
778
+
779
+ ---
780
+
781
+ ## Bundling and Test Failures
782
+
783
+ ### `waiting for wp_publisher ready` or Publisher Ready Timeout
784
+
785
+ **Symptoms:**
786
+ - Tests hang while starting servers
787
+ - Logs show `waiting for wp_publisher ready`
788
+ - Tests time out without a clear stack trace
789
+
790
+ **Likely cause:** the JS/CSS bundler failed before emitting `ready`.
791
+
792
+ **What to check:**
793
+ 1. Look earlier in the log for bundler errors (esbuild, Sass, file resolution).
794
+ 2. Confirm `sass` is installed if you are running Sass tests.
795
+ 3. Validate the client entry path passed to `src_path_client_js`.
796
+
797
+ ### esbuild platform mismatch (Windows vs WSL)
798
+
799
+ **Symptoms:**
800
+ - Error: `You installed esbuild for another platform than the one you're currently using`
801
+
802
+ **Cause:** `node_modules` was installed on a different OS and reused in this environment.
803
+
804
+ **Fix:**
805
+ 1. Remove the existing `node_modules` from the current workspace.
806
+ 2. Reinstall dependencies in the current environment:
807
+ ```bash
808
+ npm install
809
+ ```
810
+ 3. If you prefer to keep the lockfile untouched, use:
811
+ ```bash
812
+ npm ci
813
+ ```
814
+ 4. As a fast workaround, you can try:
815
+ ```bash
816
+ npm rebuild esbuild
817
+ ```
818
+
819
+ ---
820
+
821
+ Remember: Most issues can be resolved by carefully checking the console output, verifying file paths, and ensuring proper control lifecycle management. Start with the basics and work systematically through the possible causes.
@@ -64,13 +64,18 @@ if (require.main === module) {
64
64
  });
65
65
 
66
66
  // Register the SSE endpoint with the server's router
67
+ // You can use the manual approach (full control):
67
68
  server.server_router.set_route('/api/tick-stream', tick_publisher, tick_publisher.handle_http);
68
69
  console.log(' ✓ /api/tick-stream - Hot tick stream (SSE)');
69
70
 
71
+ // Or use the simplified API (auto-prefixes /api/ for simple names):
72
+ // server.publish_observable('tick-stream', tick_observable);
73
+
70
74
  // ========================================
71
75
  // Also publish a simple JSON API endpoint for comparison
72
76
  // ========================================
73
- server.publish('/api/status', () => {
77
+ // Simple name (auto-prefixes /api/)
78
+ server.publish('status', () => {
74
79
  return {
75
80
  status: 'ok',
76
81
  tick_count: tick_count,