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.
- package/.github/agents/Mobile Developer.agent.md +89 -0
- package/.github/workflows/control-scan-manifest-check.yml +31 -0
- package/AGENTS.md +4 -0
- package/README.md +215 -3
- package/admin-ui/client.js +81 -51
- package/admin-ui/v1/admin_auth_service.js +197 -0
- package/admin-ui/v1/admin_user_store.js +71 -0
- package/admin-ui/v1/client.js +17 -0
- package/admin-ui/v1/controls/admin_shell.js +1399 -0
- package/admin-ui/v1/controls/group_box.js +84 -0
- package/admin-ui/v1/controls/stat_card.js +125 -0
- package/admin-ui/v1/server.js +658 -0
- package/admin-ui/v1/utils/formatters.js +68 -0
- package/dev-status.svg +139 -0
- package/docs/admin-extension-guide.md +345 -0
- package/docs/api-reference.md +301 -43
- package/docs/books/adaptive-control-improvements/01-control-candidate-matrix.md +122 -0
- package/docs/books/adaptive-control-improvements/02-tier-1-layout-playbooks.md +207 -0
- package/docs/books/adaptive-control-improvements/03-tier-2-navigation-form-overlay.md +140 -0
- package/docs/books/adaptive-control-improvements/04-cross-cutting-platform-functionality.md +141 -0
- package/docs/books/adaptive-control-improvements/05-styling-theming-density-upgrades.md +114 -0
- package/docs/books/adaptive-control-improvements/06-testing-quality-gates.md +97 -0
- package/docs/books/adaptive-control-improvements/07-delivery-roadmap-and-ownership.md +137 -0
- package/docs/books/adaptive-control-improvements/08-appendix-tier1-acceptance-and-pr-templates.md +261 -0
- package/docs/books/adaptive-control-improvements/README.md +66 -0
- package/docs/books/admin-ui-authentication/01-threat-model-and-goals.md +124 -0
- package/docs/books/admin-ui-authentication/02-session-model-and-token-model.md +75 -0
- package/docs/books/admin-ui-authentication/03-auth-middleware-patterns.md +77 -0
- package/docs/books/admin-ui-authentication/README.md +25 -0
- package/docs/books/creating-a-new-admin-ui/01-introduction-and-vision.md +130 -0
- package/docs/books/creating-a-new-admin-ui/02-architecture-and-data-flow.md +298 -0
- package/docs/books/creating-a-new-admin-ui/03-server-introspection.md +381 -0
- package/docs/books/creating-a-new-admin-ui/04-admin-module-adapter-layer.md +592 -0
- package/docs/books/creating-a-new-admin-ui/05-domain-controls-stat-cards-and-gauges.md +513 -0
- package/docs/books/creating-a-new-admin-ui/06-domain-controls-process-manager.md +544 -0
- package/docs/books/creating-a-new-admin-ui/07-domain-controls-resource-pool-inspector.md +493 -0
- package/docs/books/creating-a-new-admin-ui/08-domain-controls-route-table-and-api-explorer.md +586 -0
- package/docs/books/creating-a-new-admin-ui/09-domain-controls-log-viewer-and-activity-feed.md +490 -0
- package/docs/books/creating-a-new-admin-ui/10-domain-controls-build-status-and-bundle-inspector.md +526 -0
- package/docs/books/creating-a-new-admin-ui/11-domain-controls-configuration-panel.md +808 -0
- package/docs/books/creating-a-new-admin-ui/12-admin-shell-layout-sidebar-navigation.md +210 -0
- package/docs/books/creating-a-new-admin-ui/13-telemetry-integration.md +556 -0
- package/docs/books/creating-a-new-admin-ui/14-realtime-sse-observable-integration.md +485 -0
- package/docs/books/creating-a-new-admin-ui/15-styling-theming-aero-design-system.md +521 -0
- package/docs/books/creating-a-new-admin-ui/16-testing-and-quality-assurance.md +147 -0
- package/docs/books/creating-a-new-admin-ui/17-next-steps-process-resource-roadmap.md +356 -0
- package/docs/books/creating-a-new-admin-ui/README.md +68 -0
- package/docs/books/device-adaptive-composition/01-platform-feature-audit.md +177 -0
- package/docs/books/device-adaptive-composition/02-responsive-composition-model.md +187 -0
- package/docs/books/device-adaptive-composition/03-data-model-vs-view-model.md +231 -0
- package/docs/books/device-adaptive-composition/04-styling-theme-breakpoints.md +234 -0
- package/docs/books/device-adaptive-composition/05-showcase-app-multi-device-assessment.md +193 -0
- package/docs/books/device-adaptive-composition/06-implementation-patterns-and-apis.md +346 -0
- package/docs/books/device-adaptive-composition/07-testing-harness-and-quality-gates.md +265 -0
- package/docs/books/device-adaptive-composition/08-roadmap-and-adoption-plan.md +250 -0
- package/docs/books/device-adaptive-composition/README.md +47 -0
- package/docs/books/jsgui3-bundling-research-book/00-table-of-contents.md +35 -0
- package/docs/books/jsgui3-bundling-research-book/01-pipeline-and-runtime-semantics.md +34 -0
- package/docs/books/jsgui3-bundling-research-book/02-javascript-bundling-core.md +36 -0
- package/docs/books/jsgui3-bundling-research-book/03-style-extraction-and-css-compilation.md +35 -0
- package/docs/books/jsgui3-bundling-research-book/04-static-publishing-and-delivery.md +39 -0
- package/docs/books/jsgui3-bundling-research-book/05-current-limits-and-size-bloat-vectors.md +25 -0
- package/docs/books/jsgui3-bundling-research-book/06-unused-module-elimination-strategy.md +77 -0
- package/docs/books/jsgui3-bundling-research-book/07-jsgui3-html-control-and-mixin-pruning.md +63 -0
- package/docs/books/jsgui3-bundling-research-book/08-test-and-verification-methodology.md +43 -0
- package/docs/books/jsgui3-bundling-research-book/09-roadmap-and-rollout.md +42 -0
- package/docs/books/jsgui3-bundling-research-book/10-further-research-strategies-and-upgrades.md +211 -0
- package/docs/books/jsgui3-bundling-research-book/README.md +35 -0
- package/docs/bundling-system-deep-dive.md +9 -4
- package/docs/comparison-report-express-plex-cpanel.md +549 -0
- package/docs/comprehensive-documentation.md +49 -18
- package/docs/configuration-reference.md +152 -27
- package/docs/core/README.md +19 -0
- package/docs/core/jsgui3-server-core-book/00-table-of-contents.md +21 -0
- package/docs/core/jsgui3-server-core-book/01-startup-readiness-state-machine.md +41 -0
- package/docs/core/jsgui3-server-core-book/02-resource-abstraction-and-lifecycle.md +92 -0
- package/docs/core/jsgui3-server-core-book/03-resource-pool-and-event-topology.md +47 -0
- package/docs/core/jsgui3-server-core-book/04-sse-publisher-semantics.md +41 -0
- package/docs/core/jsgui3-server-core-book/05-serve-factory-resource-wiring.md +46 -0
- package/docs/core/jsgui3-server-core-book/06-e2e-testing-methodology.md +48 -0
- package/docs/core/jsgui3-server-core-book/07-defect-detection-and-hardening-loop.md +47 -0
- package/docs/designs/server-admin-interface-aero.svg +611 -0
- package/docs/publishers-guide.md +59 -4
- package/docs/resources-guide.md +184 -35
- package/docs/simple-server-api-design.md +72 -17
- package/docs/system-architecture.md +18 -14
- package/docs/troubleshooting.md +84 -53
- package/examples/controls/15) window, observable SSE/server.js +6 -1
- package/examples/controls/19) window, auto observable ui/server.js +9 -0
- package/examples/controls/20) window, task manager app/README.md +133 -0
- package/examples/controls/20) window, task manager app/client.js +797 -0
- package/examples/controls/20) window, task manager app/server.js +178 -0
- package/examples/controls/6) window, color_palette/client.js +165 -68
- package/examples/controls/9) window, date picker/client.js +362 -76
- package/examples/controls/9b) window, shared data.model mirrored date pickers/client.js +104 -83
- package/examples/jsgui3-html/06) theming/client.js +22 -1
- package/examples/jsgui3-html/10) binding-debugger/client.js +137 -1
- package/http/responders/static/Static_Route_HTTP_Responder.js +52 -34
- package/lab/experiments/capture-color-controls.js +196 -0
- package/lab/results/screenshots/color-controls/full_page.png +0 -0
- package/lab/results/screenshots/color-controls/section_1_color_grid_12x12.png +0 -0
- package/lab/results/screenshots/color-controls/section_2_color_grid_4x2.png +0 -0
- package/lab/results/screenshots/color-controls/section_3_color_palette.png +0 -0
- package/lab/results/screenshots/color-controls/section_4_palette_comparison.png +0 -0
- package/lab/results/screenshots/color-controls/section_5_raw_swatches.png +0 -0
- package/lab/results/screenshots/color-controls/section_6_optimized_crayola.png +0 -0
- package/lab/results/screenshots/color-controls/section_7_pastel_palette.png +0 -0
- package/lab/results/screenshots/color-controls/section_8_extended_144.png +0 -0
- package/lab/screenshot-utils.js +248 -0
- package/module.js +12 -0
- package/package.json +12 -2
- package/publishers/Publishers.js +4 -3
- package/publishers/helpers/assigners/static-compressed-response-buffers/Single_Control_Webpage_Server_Static_Compressed_Response_Buffers_Assigner.js +5 -5
- package/publishers/http-sse-publisher.js +341 -0
- package/resources/process-resource.js +950 -0
- package/resources/processors/bundlers/js/esbuild/Advanced_JS_Bundler_Using_ESBuild.js +129 -33
- package/resources/processors/bundlers/js/esbuild/Core_JS_Non_Minifying_Bundler_Using_ESBuild.js +18 -7
- package/resources/processors/bundlers/js/esbuild/JSGUI3_HTML_Control_Optimizer.js +829 -0
- package/resources/remote-process-resource.js +355 -0
- package/resources/server-resource-pool.js +354 -41
- package/serve-factory.js +442 -259
- package/server.js +288 -13
- package/tests/README.md +71 -4
- package/tests/admin-ui-jsgui-controls.test.js +581 -0
- package/tests/admin-ui-render.test.js +24 -0
- package/tests/assigners.test.js +56 -40
- package/tests/bundling-default-control-elimination.puppeteer.test.js +260 -0
- package/tests/configuration-validation.test.js +21 -18
- package/tests/content-analysis.test.js +7 -6
- package/tests/control-optimizer-cache-behavior.test.js +52 -0
- package/tests/control-scan-manifest-regression.test.js +144 -0
- package/tests/end-to-end.test.js +15 -14
- package/tests/error-handling.test.js +222 -179
- package/tests/fixtures/bundling-default-button-client.js +37 -0
- package/tests/fixtures/bundling-default-window-client.js +34 -0
- package/tests/fixtures/control_scan_manifest_expectations.json +48 -0
- package/tests/fixtures/resource-monitor-client.js +319 -0
- package/tests/helpers/puppeteer-e2e-harness.js +317 -0
- package/tests/http-sse-publisher.test.js +136 -0
- package/tests/performance.test.js +69 -65
- package/tests/process-resource.test.js +138 -0
- package/tests/publishers.test.js +7 -7
- package/tests/remote-process-resource.test.js +160 -0
- package/tests/sass-controls.e2e.test.js +7 -1
- package/tests/serve-resources.test.js +270 -0
- package/tests/serve.test.js +120 -50
- package/tests/server-resource-pool.test.js +106 -0
- package/tests/small-controls-bundle-size.test.js +252 -0
- package/tests/test-runner.js +14 -1
- package/tests/window-examples.puppeteer.test.js +204 -1
- package/tests/window-resource-integration.puppeteer.test.js +585 -0
- package/tests/temp_invalid.js +0 -7
- package/tests/temp_invalid_utf8.js +0 -1
- package/tests/temp_malformed.js +0 -10
package/docs/publishers-guide.md
CHANGED
|
@@ -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
|
-
|
|
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
|
|
package/docs/resources-guide.md
CHANGED
|
@@ -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
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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:
|
|
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
|
|
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
|
|
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
|
-
- [
|
|
550
|
-
- [
|
|
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
|
-
- `
|
|
40
|
-
- `
|
|
41
|
-
- `
|
|
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
|
-
- `
|
|
51
|
-
- `
|
|
52
|
-
- `
|
|
53
|
-
- `
|
|
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.
|
package/docs/troubleshooting.md
CHANGED
|
@@ -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
|
-
|
|
77
|
+
// Simple name (auto-prefixes /api/)
|
|
78
|
+
server.publish('status', () => {
|
|
74
79
|
return {
|
|
75
80
|
status: 'ok',
|
|
76
81
|
tick_count: tick_count,
|