jsgui3-server 0.0.147 → 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.
Files changed (145) hide show
  1. package/.github/workflows/control-scan-manifest-check.yml +31 -0
  2. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-071799b982906680f5fd699d.js +40 -0
  3. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-07352945ad5c92654fcb8b65.js +39 -0
  4. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-138a601fadb6191ea314c6fd.js +39 -0
  5. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-171f6c381c2cadf2e9fa7087.js +39 -0
  6. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-1d973388156b84a04373fac9.js +39 -0
  7. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-20e117bc8a10d2cd16234bbe.js +40 -0
  8. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-2b028a82b0e5efddba42425f.js +39 -0
  9. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-4518556cd5c7e059e82b22b8.js +40 -0
  10. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-5bac1aa0f213902f718ed74f.js +40 -0
  11. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-5f9996ac7822caf777d92f56.js +39 -0
  12. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-60a92c702e65fd9cf748e3ec.js +39 -0
  13. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-6164c1f8f738995c541895d2.js +44 -0
  14. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-6718a85eb9e5aa782dd47a05.js +45 -0
  15. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-69e280f14e37aee76a1d4675.js +39 -0
  16. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7570d1b030d44b111ed59c4c.js +39 -0
  17. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7798c9bbd55e510d5039f936.js +42 -0
  18. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-78cd511ea1ef18ecb03d1be5.js +40 -0
  19. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7d482e0b95bcb5e3c543118b.js +43 -0
  20. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-80e9476d1127c55b40fdb36f.js +40 -0
  21. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-810ced55d5320a3088a05b13.js +40 -0
  22. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-8423565f1a40e329afc8c6cf.js +40 -0
  23. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-900bef783b8cee36506ec282.js +39 -0
  24. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-a1a37aff6416fdad74040ddf.js +39 -0
  25. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-ad48d5e8eda40f175b4df090.js +39 -0
  26. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-aec5a2d963015528c9099462.js +39 -0
  27. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-af9d34e0f1722fab9e28c269.js +39 -0
  28. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-b818e4015e2f1fe86280b5ab.js +41 -0
  29. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-bcb2541adc70b7aba61768c5.js +44 -0
  30. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-bfe89d2c78ed44f95ed7dd73.js +40 -0
  31. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-c06f04806a1e688e1187110c.js +40 -0
  32. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-c3f3adf904f585afc544b96a.js +39 -0
  33. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-d45acb873e1d8e32d5e60f2e.js +39 -0
  34. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-db06f132533706f4a0163b8c.js +39 -0
  35. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-f660f40d78b135fc8560a862.js +39 -0
  36. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-f9dee4ec18a96e09bee06bae.js +39 -0
  37. package/README.md +85 -3
  38. package/admin-ui/client.js +213 -0
  39. package/admin-ui/server.js +104 -0
  40. package/client/controls/auto-observable.js +207 -0
  41. package/dev-status.svg +139 -0
  42. package/docs/api-reference.md +301 -43
  43. package/docs/books/admin-ui/01-introduction.md +32 -0
  44. package/docs/books/admin-ui/02-architecture.md +92 -0
  45. package/docs/books/admin-ui/03-controls.md +194 -0
  46. package/docs/books/admin-ui/04-implementation-plan.md +62 -0
  47. package/docs/books/admin-ui/README.md +26 -0
  48. package/docs/books/jsgui3-bundling-research-book/00-table-of-contents.md +35 -0
  49. package/docs/books/jsgui3-bundling-research-book/01-pipeline-and-runtime-semantics.md +34 -0
  50. package/docs/books/jsgui3-bundling-research-book/02-javascript-bundling-core.md +36 -0
  51. package/docs/books/jsgui3-bundling-research-book/03-style-extraction-and-css-compilation.md +35 -0
  52. package/docs/books/jsgui3-bundling-research-book/04-static-publishing-and-delivery.md +39 -0
  53. package/docs/books/jsgui3-bundling-research-book/05-current-limits-and-size-bloat-vectors.md +25 -0
  54. package/docs/books/jsgui3-bundling-research-book/06-unused-module-elimination-strategy.md +77 -0
  55. package/docs/books/jsgui3-bundling-research-book/07-jsgui3-html-control-and-mixin-pruning.md +63 -0
  56. package/docs/books/jsgui3-bundling-research-book/08-test-and-verification-methodology.md +43 -0
  57. package/docs/books/jsgui3-bundling-research-book/09-roadmap-and-rollout.md +42 -0
  58. package/docs/books/jsgui3-bundling-research-book/10-further-research-strategies-and-upgrades.md +211 -0
  59. package/docs/books/jsgui3-bundling-research-book/README.md +35 -0
  60. package/docs/bundling-system-deep-dive.md +9 -4
  61. package/docs/comprehensive-documentation.md +49 -18
  62. package/docs/configuration-reference.md +152 -27
  63. package/docs/core/README.md +19 -0
  64. package/docs/core/jsgui3-server-core-book/00-table-of-contents.md +21 -0
  65. package/docs/core/jsgui3-server-core-book/01-startup-readiness-state-machine.md +41 -0
  66. package/docs/core/jsgui3-server-core-book/02-resource-abstraction-and-lifecycle.md +92 -0
  67. package/docs/core/jsgui3-server-core-book/03-resource-pool-and-event-topology.md +47 -0
  68. package/docs/core/jsgui3-server-core-book/04-sse-publisher-semantics.md +41 -0
  69. package/docs/core/jsgui3-server-core-book/05-serve-factory-resource-wiring.md +46 -0
  70. package/docs/core/jsgui3-server-core-book/06-e2e-testing-methodology.md +48 -0
  71. package/docs/core/jsgui3-server-core-book/07-defect-detection-and-hardening-loop.md +47 -0
  72. package/docs/publishers-guide.md +59 -4
  73. package/docs/resources-guide.md +184 -35
  74. package/docs/simple-server-api-design.md +72 -17
  75. package/docs/system-architecture.md +18 -14
  76. package/examples/controls/15) window, observable SSE/server.js +6 -1
  77. package/examples/controls/19) window, auto observable ui/client.js +125 -0
  78. package/examples/controls/19) window, auto observable ui/server.js +73 -0
  79. package/examples/controls/20) window, task manager app/README.md +133 -0
  80. package/examples/controls/20) window, task manager app/client.js +797 -0
  81. package/examples/controls/20) window, task manager app/server.js +178 -0
  82. package/examples/controls/6) window, color_palette/client.js +165 -68
  83. package/examples/controls/9) window, date picker/client.js +362 -76
  84. package/examples/controls/9b) window, shared data.model mirrored date pickers/client.js +104 -83
  85. package/examples/jsgui3-html/06) theming/client.js +22 -1
  86. package/examples/jsgui3-html/10) binding-debugger/client.js +137 -1
  87. package/http/responders/static/Static_Route_HTTP_Responder.js +52 -34
  88. package/lab/experiments/capture-color-controls.js +196 -0
  89. package/lab/results/screenshots/color-controls/full_page.png +0 -0
  90. package/lab/results/screenshots/color-controls/section_1_color_grid_12x12.png +0 -0
  91. package/lab/results/screenshots/color-controls/section_2_color_grid_4x2.png +0 -0
  92. package/lab/results/screenshots/color-controls/section_3_color_palette.png +0 -0
  93. package/lab/results/screenshots/color-controls/section_4_palette_comparison.png +0 -0
  94. package/lab/results/screenshots/color-controls/section_5_raw_swatches.png +0 -0
  95. package/lab/results/screenshots/color-controls/section_6_optimized_crayola.png +0 -0
  96. package/lab/results/screenshots/color-controls/section_7_pastel_palette.png +0 -0
  97. package/lab/results/screenshots/color-controls/section_8_extended_144.png +0 -0
  98. package/lab/screenshot-utils.js +248 -0
  99. package/module.js +11 -4
  100. package/package.json +14 -4
  101. package/publishers/Publishers.js +4 -3
  102. package/publishers/helpers/assigners/static-compressed-response-buffers/Single_Control_Webpage_Server_Static_Compressed_Response_Buffers_Assigner.js +5 -5
  103. package/publishers/http-observable-publisher.js +8 -0
  104. package/publishers/http-sse-publisher.js +341 -0
  105. package/publishers/http-webpage-publisher.js +13 -3
  106. package/publishers/http-webpageorsite-publisher.js +18 -0
  107. package/resources/process-resource.js +950 -0
  108. package/resources/processors/bundlers/js/esbuild/Advanced_JS_Bundler_Using_ESBuild.js +164 -46
  109. package/resources/processors/bundlers/js/esbuild/Core_JS_Non_Minifying_Bundler_Using_ESBuild.js +18 -7
  110. package/resources/processors/bundlers/js/esbuild/JSGUI3_HTML_Control_Optimizer.js +829 -0
  111. package/resources/remote-process-resource.js +355 -0
  112. package/resources/server-resource-pool.js +354 -41
  113. package/serve-factory.js +441 -259
  114. package/server.js +161 -16
  115. package/tests/README.md +66 -4
  116. package/tests/admin-ui-render.test.js +24 -0
  117. package/tests/assigners.test.js +56 -40
  118. package/tests/bundling-default-control-elimination.puppeteer.test.js +260 -0
  119. package/tests/configuration-validation.test.js +21 -18
  120. package/tests/content-analysis.test.js +7 -6
  121. package/tests/control-optimizer-cache-behavior.test.js +52 -0
  122. package/tests/control-scan-manifest-regression.test.js +144 -0
  123. package/tests/end-to-end.test.js +15 -14
  124. package/tests/error-handling.test.js +222 -179
  125. package/tests/fixtures/bundling-default-button-client.js +37 -0
  126. package/tests/fixtures/bundling-default-window-client.js +34 -0
  127. package/tests/fixtures/control_scan_manifest_expectations.json +48 -0
  128. package/tests/fixtures/resource-monitor-client.js +319 -0
  129. package/tests/helpers/puppeteer-e2e-harness.js +317 -0
  130. package/tests/http-sse-publisher.test.js +136 -0
  131. package/tests/performance.test.js +69 -65
  132. package/tests/process-resource.test.js +138 -0
  133. package/tests/publishers.test.js +7 -7
  134. package/tests/remote-process-resource.test.js +160 -0
  135. package/tests/sass-controls.e2e.test.js +7 -1
  136. package/tests/serve-resources.test.js +270 -0
  137. package/tests/serve.test.js +120 -50
  138. package/tests/server-resource-pool.test.js +106 -0
  139. package/tests/small-controls-bundle-size.test.js +252 -0
  140. package/tests/test-runner.js +13 -1
  141. package/tests/window-examples.puppeteer.test.js +204 -1
  142. package/tests/window-resource-integration.puppeteer.test.js +585 -0
  143. package/tests/temp_invalid.js +0 -7
  144. package/tests/temp_invalid_utf8.js +0 -1
  145. package/tests/temp_malformed.js +0 -10
@@ -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.
@@ -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,
@@ -0,0 +1,125 @@
1
+ const jsgui = require('jsgui3-client');
2
+ const { controls, Control } = jsgui;
3
+ const Auto_Observable_UI = require('../../../client/controls/auto-observable');
4
+ controls.Auto_Observable_UI = Auto_Observable_UI;
5
+
6
+ const Active_HTML_Document = require('../../../controls/Active_HTML_Document');
7
+
8
+ class Demo_Page extends Active_HTML_Document {
9
+ constructor(spec = {}) {
10
+ spec.__type_name = spec.__type_name || 'demo_page';
11
+ super(spec);
12
+ const { context } = this;
13
+
14
+ if (typeof this.body.add_class === 'function') {
15
+ this.body.add_class('demo-page');
16
+ }
17
+
18
+ const compose = () => {
19
+ const h1 = new controls.h1({ context });
20
+ h1.add('Auto Observable UI Demo');
21
+ this.body.add(h1);
22
+
23
+ const container = new controls.div({ context, class: 'params-container' });
24
+ this.body.add(container);
25
+
26
+ // 1. Tick Counter (Int)
27
+ const ui_tick = new Auto_Observable_UI({
28
+ context,
29
+ url: '/api/tick',
30
+ class: 'param-ui'
31
+ });
32
+ container.add(ui_tick);
33
+
34
+ // 2. CPU Load (Gauge)
35
+ const ui_cpu = new Auto_Observable_UI({
36
+ context,
37
+ url: '/api/cpu',
38
+ class: 'param-ui'
39
+ });
40
+ container.add(ui_cpu);
41
+
42
+ // 3. System Logs (Log)
43
+ const ui_log = new Auto_Observable_UI({
44
+ context,
45
+ url: '/api/logs',
46
+ class: 'param-ui span-2'
47
+ });
48
+ container.add(ui_log);
49
+ };
50
+
51
+ if (!spec.el) {
52
+ compose();
53
+ }
54
+ }
55
+ }
56
+
57
+ Demo_Page.css = `
58
+ body {
59
+ background: #222;
60
+ color: #eee;
61
+ font-family: sans-serif;
62
+ padding: 20px;
63
+ }
64
+ .params-container {
65
+ display: grid;
66
+ grid-template-columns: 1fr 1fr;
67
+ gap: 20px;
68
+ max-width: 800px;
69
+ }
70
+ .param-ui {
71
+ background: #333;
72
+ padding: 15px;
73
+ border-radius: 8px;
74
+ box-shadow: 0 2px 10px rgba(0,0,0,0.5);
75
+ }
76
+ .span-2 {
77
+ grid-column: span 2;
78
+ }
79
+ .value-display {
80
+ text-align: center;
81
+ }
82
+ .value-text {
83
+ font-size: 3em;
84
+ font-weight: bold;
85
+ color: #4facfe;
86
+ }
87
+ .progress-bg {
88
+ background: #444;
89
+ height: 20px;
90
+ border-radius: 10px;
91
+ overflow: hidden;
92
+ margin: 10px 0;
93
+ }
94
+ .progress-fill {
95
+ background: linear-gradient(90deg, #4facfe 0%, #00f2fe 100%);
96
+ height: 100%;
97
+ width: 0%;
98
+ transition: width 0.3s ease;
99
+ }
100
+ .log-area {
101
+ height: 150px;
102
+ background: #111;
103
+ overflow-y: auto;
104
+ text-align: left;
105
+ padding: 10px;
106
+ font-family: monospace;
107
+ font-size: 0.9em;
108
+ border: 1px solid #444;
109
+ }
110
+ .log-entry {
111
+ margin-bottom: 4px;
112
+ border-bottom: 1px solid #222;
113
+ }
114
+ .status-indicator {
115
+ font-size: 0.8em;
116
+ text-transform: uppercase;
117
+ margin-bottom: 5px;
118
+ color: #888;
119
+ }
120
+ .status-connected { color: #0f0; }
121
+ .status-error { color: #f00; }
122
+ `;
123
+
124
+ module.exports = jsgui;
125
+ controls.Demo_Page = Demo_Page;
@@ -0,0 +1,73 @@
1
+ const jsgui = require('./client');
2
+ const Server = require('../../../server');
3
+ const { Demo_Page } = jsgui.controls;
4
+ const { observable } = require('fnl');
5
+
6
+ if (require.main === module) {
7
+ const server = new Server({
8
+ Ctrl: Demo_Page,
9
+ src_path_client_js: require.resolve('./client.js')
10
+ });
11
+
12
+ server.on('ready', () => {
13
+ // 1. Tick Observable
14
+ const obs_tick = observable((next) => {
15
+ let i = 0;
16
+ const timer = setInterval(() => next(++i), 1000);
17
+ return () => clearInterval(timer);
18
+ });
19
+ // Attach schema manually (or could be done via helper)
20
+ obs_tick.schema = {
21
+ name: 'Uptime (Seconds)',
22
+ type: 'int'
23
+ };
24
+ server.publish_observable('/api/tick', obs_tick);
25
+
26
+ // 2. CPU Observable (Simulated)
27
+ const obs_cpu = observable((next) => {
28
+ const timer = setInterval(() => {
29
+ const load = 40 + Math.random() * 30;
30
+ next(Math.floor(load));
31
+ }, 500);
32
+ return () => clearInterval(timer);
33
+ });
34
+ obs_cpu.schema = {
35
+ name: 'CPU Load',
36
+ type: 'number',
37
+ min: 0,
38
+ max: 100
39
+ };
40
+ server.publish_observable('/api/cpu', obs_cpu);
41
+
42
+ // 3. Logs Observable
43
+ const obs_logs = observable((next) => {
44
+ const msgs = ['System check OK', 'Request received', 'Cache invalidated', 'User login', 'Background job started'];
45
+ const timer = setInterval(() => {
46
+ const msg = msgs[Math.floor(Math.random() * msgs.length)];
47
+ next({ message: msg, level: 'info' });
48
+ }, 2000);
49
+ return () => clearInterval(timer);
50
+ });
51
+ obs_logs.schema = {
52
+ name: 'Server Logs',
53
+ type: 'log'
54
+ };
55
+ server.publish_observable('/api/logs', obs_logs);
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
+
66
+ // Start
67
+ const port = 52100;
68
+ server.start(port, (err) => {
69
+ if (err) throw err;
70
+ console.log(`Demo running at http://localhost:${port}`);
71
+ });
72
+ });
73
+ }
@@ -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