jsgui3-server 0.0.148 → 0.0.149
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/workflows/control-scan-manifest-check.yml +31 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-071799b982906680f5fd699d.js +40 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-07352945ad5c92654fcb8b65.js +39 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-138a601fadb6191ea314c6fd.js +39 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-171f6c381c2cadf2e9fa7087.js +39 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-1d973388156b84a04373fac9.js +39 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-20e117bc8a10d2cd16234bbe.js +40 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-2b028a82b0e5efddba42425f.js +39 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-4518556cd5c7e059e82b22b8.js +40 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-5bac1aa0f213902f718ed74f.js +40 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-5f9996ac7822caf777d92f56.js +39 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-60a92c702e65fd9cf748e3ec.js +39 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-6164c1f8f738995c541895d2.js +44 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-6718a85eb9e5aa782dd47a05.js +45 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-69e280f14e37aee76a1d4675.js +39 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7570d1b030d44b111ed59c4c.js +39 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7798c9bbd55e510d5039f936.js +42 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-78cd511ea1ef18ecb03d1be5.js +40 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7d482e0b95bcb5e3c543118b.js +43 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-80e9476d1127c55b40fdb36f.js +40 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-810ced55d5320a3088a05b13.js +40 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-8423565f1a40e329afc8c6cf.js +40 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-900bef783b8cee36506ec282.js +39 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-a1a37aff6416fdad74040ddf.js +39 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-ad48d5e8eda40f175b4df090.js +39 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-aec5a2d963015528c9099462.js +39 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-af9d34e0f1722fab9e28c269.js +39 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-b818e4015e2f1fe86280b5ab.js +41 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-bcb2541adc70b7aba61768c5.js +44 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-bfe89d2c78ed44f95ed7dd73.js +40 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-c06f04806a1e688e1187110c.js +40 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-c3f3adf904f585afc544b96a.js +39 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-d45acb873e1d8e32d5e60f2e.js +39 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-db06f132533706f4a0163b8c.js +39 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-f660f40d78b135fc8560a862.js +39 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-f9dee4ec18a96e09bee06bae.js +39 -0
- package/README.md +85 -3
- package/admin-ui/client.js +8 -8
- package/dev-status.svg +139 -0
- package/docs/api-reference.md +301 -43
- 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/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/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/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 +11 -4
- 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 +441 -259
- package/server.js +89 -13
- package/tests/README.md +66 -4
- 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 +13 -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/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.
|
|
@@ -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,
|
|
@@ -54,6 +54,15 @@ if (require.main === module) {
|
|
|
54
54
|
};
|
|
55
55
|
server.publish_observable('/api/logs', obs_logs);
|
|
56
56
|
|
|
57
|
+
// Expose Status Diagram
|
|
58
|
+
server.publish('/dev-status.svg', (req, res) => {
|
|
59
|
+
const fs = require('fs');
|
|
60
|
+
const path = require('path');
|
|
61
|
+
const filePath = path.join(__dirname, '../../../../dev-status.svg');
|
|
62
|
+
res.setHeader('Content-Type', 'image/svg+xml');
|
|
63
|
+
fs.createReadStream(filePath).pipe(res);
|
|
64
|
+
});
|
|
65
|
+
|
|
57
66
|
// Start
|
|
58
67
|
const port = 52100;
|
|
59
68
|
server.start(port, (err) => {
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# 20) Task Manager Application
|
|
2
|
+
|
|
3
|
+
A comprehensive example demonstrating a multi-window task management application built with jsgui3.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Multiple Windows**: Main task manager window + floating quick-add window
|
|
8
|
+
- **Tabbed Interface**: Tasks, Projects, and Stats tabs in the main window
|
|
9
|
+
- **Data Binding**: Uses `Data_Object` and `field()` for reactive state management
|
|
10
|
+
- **API Integration**: Full CRUD operations via `server.publish()` endpoints
|
|
11
|
+
- **Interactive Controls**: Checkboxes, text inputs, select dropdowns, buttons
|
|
12
|
+
- **Real-time Updates**: UI updates immediately after API responses
|
|
13
|
+
- **Statistics Dashboard**: Tracks completion rates with visual progress bar
|
|
14
|
+
|
|
15
|
+
## Running the Example
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
cd examples/controls/20) window, task manager app
|
|
19
|
+
node server.js
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Then open http://localhost:52021 in your browser.
|
|
23
|
+
|
|
24
|
+
## Architecture
|
|
25
|
+
|
|
26
|
+
### Client (`client.js`)
|
|
27
|
+
|
|
28
|
+
The `Task_Manager_App` class extends `Active_HTML_Document` and demonstrates:
|
|
29
|
+
|
|
30
|
+
1. **Data Model Setup**:
|
|
31
|
+
```javascript
|
|
32
|
+
this.data = { model: new Data_Object({ context }) };
|
|
33
|
+
field(this.data.model, 'tasks');
|
|
34
|
+
field(this.data.model, 'projects');
|
|
35
|
+
field(this.data.model, 'stats');
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
2. **Multiple Windows**:
|
|
39
|
+
```javascript
|
|
40
|
+
const main_window = new controls.Window({ context, title: 'Task Manager', pos: [20, 20] });
|
|
41
|
+
const quick_add_window = new controls.Window({ context, title: 'Quick Add Task', pos: [540, 20] });
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
3. **Tabbed Panel**:
|
|
45
|
+
```javascript
|
|
46
|
+
const main_tabs = new controls.Tabbed_Panel({
|
|
47
|
+
context,
|
|
48
|
+
tabs: [
|
|
49
|
+
['Tasks', this._create_tasks_panel(context)],
|
|
50
|
+
['Projects', this._create_projects_panel(context)],
|
|
51
|
+
['Stats', this._create_stats_panel(context)]
|
|
52
|
+
]
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
4. **API Calls**:
|
|
57
|
+
```javascript
|
|
58
|
+
async _add_task() {
|
|
59
|
+
const response = await fetch('/api/tasks/add', {
|
|
60
|
+
method: 'POST',
|
|
61
|
+
headers: { 'Content-Type': 'application/json' },
|
|
62
|
+
body: JSON.stringify({ text, project })
|
|
63
|
+
});
|
|
64
|
+
const result = await response.json();
|
|
65
|
+
// Update UI...
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Server (`server.js`)
|
|
70
|
+
|
|
71
|
+
Uses the simple `server.publish()` API for endpoints:
|
|
72
|
+
|
|
73
|
+
```javascript
|
|
74
|
+
// GET /api/tasks/list
|
|
75
|
+
server.publish('tasks/list', () => ({ tasks: get_tasks() }));
|
|
76
|
+
|
|
77
|
+
// POST /api/tasks/add
|
|
78
|
+
server.publish('tasks/add', (data) => {
|
|
79
|
+
const new_task = { id: next_id++, text: data.text, ... };
|
|
80
|
+
tasks.push(new_task);
|
|
81
|
+
return { success: true, tasks: get_tasks() };
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## API Endpoints
|
|
86
|
+
|
|
87
|
+
| Method | Endpoint | Description |
|
|
88
|
+
|--------|----------|-------------|
|
|
89
|
+
| GET | `/api/tasks/list` | Get all tasks |
|
|
90
|
+
| POST | `/api/tasks/add` | Add a new task |
|
|
91
|
+
| POST | `/api/tasks/toggle` | Toggle task completion |
|
|
92
|
+
| POST | `/api/tasks/delete` | Delete a task |
|
|
93
|
+
| POST | `/api/tasks/clear-completed` | Remove completed tasks |
|
|
94
|
+
| GET | `/api/stats` | Get statistics by project |
|
|
95
|
+
|
|
96
|
+
## UI Components Used
|
|
97
|
+
|
|
98
|
+
- `Window` - Draggable, resizable window containers
|
|
99
|
+
- `Tabbed_Panel` - Tab navigation between views
|
|
100
|
+
- `Text_Field` - Text input for task descriptions
|
|
101
|
+
- `Select_Options` - Dropdown for project selection
|
|
102
|
+
- `Button` - Action buttons with click handlers
|
|
103
|
+
- `Checkbox` - Task completion (rendered dynamically)
|
|
104
|
+
|
|
105
|
+
## Key Patterns Demonstrated
|
|
106
|
+
|
|
107
|
+
1. **Control References**: Storing component references for later access
|
|
108
|
+
```javascript
|
|
109
|
+
this._ctrl_fields = { main_window, main_tabs, quick_add_window };
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
2. **Conditional Composition**: Only compose if not hydrating from DOM
|
|
113
|
+
```javascript
|
|
114
|
+
if (!spec.el) { compose(); }
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
3. **Activation Guard**: Prevent double-activation
|
|
118
|
+
```javascript
|
|
119
|
+
if (!this.__active) { super.activate(); ... }
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
4. **CSS as Static Property**: Scoped styles
|
|
123
|
+
```javascript
|
|
124
|
+
Task_Manager_App.css = `...`;
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Customization Ideas
|
|
128
|
+
|
|
129
|
+
- Add task due dates with `Date_Picker`
|
|
130
|
+
- Implement drag-and-drop task reordering
|
|
131
|
+
- Add task priority levels
|
|
132
|
+
- Connect to a real database instead of in-memory store
|
|
133
|
+
- Add real-time updates with `publish_observable` for multi-user sync
|