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/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-bfe89d2c78ed44f95ed7dd73.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const jsgui = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/html-core/html-core.js');
|
|
2
|
+
jsgui.Router = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/router/router.js');
|
|
3
|
+
jsgui.Resource = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/resource.js');
|
|
4
|
+
jsgui.Resource_Pool = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/pool.js');
|
|
5
|
+
jsgui.Resource.Data_KV = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/data-kv-resource.js');
|
|
6
|
+
jsgui.Resource.Data_Transform = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/data-transform-resource.js');
|
|
7
|
+
jsgui.Resource.Compilation = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/compilation-resource.js');
|
|
8
|
+
jsgui.Resource.Compiler = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/compiler-resource.js');
|
|
9
|
+
jsgui.gfx = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/node_modules/jsgui3-gfx-core/core/gfx-core.js');
|
|
10
|
+
jsgui.Resource.load_compiler = (name, jsfn, options) => {
|
|
11
|
+
const compiler_name = name;
|
|
12
|
+
const compiler_fn = jsfn;
|
|
13
|
+
const compiler_options = options || {};
|
|
14
|
+
if (typeof compiler_name !== 'string' || compiler_name.length === 0) {
|
|
15
|
+
throw new Error('Resource.load_compiler(name, fn, options) requires a non-empty string name');
|
|
16
|
+
}
|
|
17
|
+
if (typeof compiler_fn !== 'function') {
|
|
18
|
+
throw new Error('Resource.load_compiler(name, fn, options) requires a function compiler implementation');
|
|
19
|
+
}
|
|
20
|
+
const compiler_resource = new jsgui.Resource.Compiler({ name: compiler_name });
|
|
21
|
+
compiler_resource.transform = (input, transform_options = {}) => {
|
|
22
|
+
const merged_options = Object.assign({}, compiler_options, transform_options);
|
|
23
|
+
return compiler_fn(input, merged_options);
|
|
24
|
+
};
|
|
25
|
+
jsgui.Resource.compilers = jsgui.Resource.compilers || {};
|
|
26
|
+
jsgui.Resource.compilers[compiler_name] = compiler_resource;
|
|
27
|
+
const pool = compiler_options.pool || compiler_options.resource_pool;
|
|
28
|
+
if (pool && typeof pool.add === 'function') {
|
|
29
|
+
pool.add(compiler_resource);
|
|
30
|
+
}
|
|
31
|
+
return compiler_resource;
|
|
32
|
+
};
|
|
33
|
+
jsgui.controls = jsgui.controls || {};
|
|
34
|
+
Object.assign(jsgui.controls, {
|
|
35
|
+
Active_HTML_Document: require('/mnt/c/Users/james/Documents/repos/jsgui3-html/controls/organised/1-standard/5-ui/Active_HTML_Document'),
|
|
36
|
+
Button: require('/mnt/c/Users/james/Documents/repos/jsgui3-html/controls/organised/0-core/0-basic/0-native-compositional/button')
|
|
37
|
+
});
|
|
38
|
+
Object.assign(jsgui, jsgui.controls);
|
|
39
|
+
jsgui.mixins = jsgui.mx = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/control_mixins/mx.js');
|
|
40
|
+
module.exports = jsgui;
|
package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-c06f04806a1e688e1187110c.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const jsgui = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/html-core/html-core.js');
|
|
2
|
+
jsgui.Router = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/router/router.js');
|
|
3
|
+
jsgui.Resource = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/resource.js');
|
|
4
|
+
jsgui.Resource_Pool = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/pool.js');
|
|
5
|
+
jsgui.Resource.Data_KV = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/data-kv-resource.js');
|
|
6
|
+
jsgui.Resource.Data_Transform = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/data-transform-resource.js');
|
|
7
|
+
jsgui.Resource.Compilation = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/compilation-resource.js');
|
|
8
|
+
jsgui.Resource.Compiler = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/compiler-resource.js');
|
|
9
|
+
jsgui.gfx = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/node_modules/jsgui3-gfx-core/core/gfx-core.js');
|
|
10
|
+
jsgui.Resource.load_compiler = (name, jsfn, options) => {
|
|
11
|
+
const compiler_name = name;
|
|
12
|
+
const compiler_fn = jsfn;
|
|
13
|
+
const compiler_options = options || {};
|
|
14
|
+
if (typeof compiler_name !== 'string' || compiler_name.length === 0) {
|
|
15
|
+
throw new Error('Resource.load_compiler(name, fn, options) requires a non-empty string name');
|
|
16
|
+
}
|
|
17
|
+
if (typeof compiler_fn !== 'function') {
|
|
18
|
+
throw new Error('Resource.load_compiler(name, fn, options) requires a function compiler implementation');
|
|
19
|
+
}
|
|
20
|
+
const compiler_resource = new jsgui.Resource.Compiler({ name: compiler_name });
|
|
21
|
+
compiler_resource.transform = (input, transform_options = {}) => {
|
|
22
|
+
const merged_options = Object.assign({}, compiler_options, transform_options);
|
|
23
|
+
return compiler_fn(input, merged_options);
|
|
24
|
+
};
|
|
25
|
+
jsgui.Resource.compilers = jsgui.Resource.compilers || {};
|
|
26
|
+
jsgui.Resource.compilers[compiler_name] = compiler_resource;
|
|
27
|
+
const pool = compiler_options.pool || compiler_options.resource_pool;
|
|
28
|
+
if (pool && typeof pool.add === 'function') {
|
|
29
|
+
pool.add(compiler_resource);
|
|
30
|
+
}
|
|
31
|
+
return compiler_resource;
|
|
32
|
+
};
|
|
33
|
+
jsgui.controls = jsgui.controls || {};
|
|
34
|
+
Object.assign(jsgui.controls, {
|
|
35
|
+
Active_HTML_Document: require('/mnt/c/Users/james/Documents/repos/jsgui3-html/controls/organised/1-standard/5-ui/Active_HTML_Document'),
|
|
36
|
+
Window: require('/mnt/c/Users/james/Documents/repos/jsgui3-html/controls/organised/1-standard/6-layout/window')
|
|
37
|
+
});
|
|
38
|
+
Object.assign(jsgui, jsgui.controls);
|
|
39
|
+
jsgui.mixins = jsgui.mx = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/control_mixins/mx.js');
|
|
40
|
+
module.exports = jsgui;
|
package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-c3f3adf904f585afc544b96a.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const jsgui = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/html-core/html-core.js');
|
|
2
|
+
jsgui.Router = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/router/router.js');
|
|
3
|
+
jsgui.Resource = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/resource.js');
|
|
4
|
+
jsgui.Resource_Pool = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/pool.js');
|
|
5
|
+
jsgui.Resource.Data_KV = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/data-kv-resource.js');
|
|
6
|
+
jsgui.Resource.Data_Transform = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/data-transform-resource.js');
|
|
7
|
+
jsgui.Resource.Compilation = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/compilation-resource.js');
|
|
8
|
+
jsgui.Resource.Compiler = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/compiler-resource.js');
|
|
9
|
+
jsgui.gfx = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/node_modules/jsgui3-gfx-core/core/gfx-core.js');
|
|
10
|
+
jsgui.Resource.load_compiler = (name, jsfn, options) => {
|
|
11
|
+
const compiler_name = name;
|
|
12
|
+
const compiler_fn = jsfn;
|
|
13
|
+
const compiler_options = options || {};
|
|
14
|
+
if (typeof compiler_name !== 'string' || compiler_name.length === 0) {
|
|
15
|
+
throw new Error('Resource.load_compiler(name, fn, options) requires a non-empty string name');
|
|
16
|
+
}
|
|
17
|
+
if (typeof compiler_fn !== 'function') {
|
|
18
|
+
throw new Error('Resource.load_compiler(name, fn, options) requires a function compiler implementation');
|
|
19
|
+
}
|
|
20
|
+
const compiler_resource = new jsgui.Resource.Compiler({ name: compiler_name });
|
|
21
|
+
compiler_resource.transform = (input, transform_options = {}) => {
|
|
22
|
+
const merged_options = Object.assign({}, compiler_options, transform_options);
|
|
23
|
+
return compiler_fn(input, merged_options);
|
|
24
|
+
};
|
|
25
|
+
jsgui.Resource.compilers = jsgui.Resource.compilers || {};
|
|
26
|
+
jsgui.Resource.compilers[compiler_name] = compiler_resource;
|
|
27
|
+
const pool = compiler_options.pool || compiler_options.resource_pool;
|
|
28
|
+
if (pool && typeof pool.add === 'function') {
|
|
29
|
+
pool.add(compiler_resource);
|
|
30
|
+
}
|
|
31
|
+
return compiler_resource;
|
|
32
|
+
};
|
|
33
|
+
jsgui.controls = jsgui.controls || {};
|
|
34
|
+
Object.assign(jsgui.controls, {
|
|
35
|
+
Window: require('/mnt/c/Users/james/Documents/repos/jsgui3-html/controls/organised/1-standard/6-layout/window')
|
|
36
|
+
});
|
|
37
|
+
Object.assign(jsgui, jsgui.controls);
|
|
38
|
+
jsgui.mixins = jsgui.mx = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/control_mixins/mx.js');
|
|
39
|
+
module.exports = jsgui;
|
package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-d45acb873e1d8e32d5e60f2e.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const jsgui = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/html-core/html-core.js');
|
|
2
|
+
jsgui.Router = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/router/router.js');
|
|
3
|
+
jsgui.Resource = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/resource.js');
|
|
4
|
+
jsgui.Resource_Pool = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/pool.js');
|
|
5
|
+
jsgui.Resource.Data_KV = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/data-kv-resource.js');
|
|
6
|
+
jsgui.Resource.Data_Transform = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/data-transform-resource.js');
|
|
7
|
+
jsgui.Resource.Compilation = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/compilation-resource.js');
|
|
8
|
+
jsgui.Resource.Compiler = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/compiler-resource.js');
|
|
9
|
+
jsgui.gfx = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/node_modules/jsgui3-gfx-core/core/gfx-core.js');
|
|
10
|
+
jsgui.Resource.load_compiler = (name, jsfn, options) => {
|
|
11
|
+
const compiler_name = name;
|
|
12
|
+
const compiler_fn = jsfn;
|
|
13
|
+
const compiler_options = options || {};
|
|
14
|
+
if (typeof compiler_name !== 'string' || compiler_name.length === 0) {
|
|
15
|
+
throw new Error('Resource.load_compiler(name, fn, options) requires a non-empty string name');
|
|
16
|
+
}
|
|
17
|
+
if (typeof compiler_fn !== 'function') {
|
|
18
|
+
throw new Error('Resource.load_compiler(name, fn, options) requires a function compiler implementation');
|
|
19
|
+
}
|
|
20
|
+
const compiler_resource = new jsgui.Resource.Compiler({ name: compiler_name });
|
|
21
|
+
compiler_resource.transform = (input, transform_options = {}) => {
|
|
22
|
+
const merged_options = Object.assign({}, compiler_options, transform_options);
|
|
23
|
+
return compiler_fn(input, merged_options);
|
|
24
|
+
};
|
|
25
|
+
jsgui.Resource.compilers = jsgui.Resource.compilers || {};
|
|
26
|
+
jsgui.Resource.compilers[compiler_name] = compiler_resource;
|
|
27
|
+
const pool = compiler_options.pool || compiler_options.resource_pool;
|
|
28
|
+
if (pool && typeof pool.add === 'function') {
|
|
29
|
+
pool.add(compiler_resource);
|
|
30
|
+
}
|
|
31
|
+
return compiler_resource;
|
|
32
|
+
};
|
|
33
|
+
jsgui.controls = jsgui.controls || {};
|
|
34
|
+
Object.assign(jsgui.controls, {
|
|
35
|
+
|
|
36
|
+
});
|
|
37
|
+
Object.assign(jsgui, jsgui.controls);
|
|
38
|
+
jsgui.mixins = jsgui.mx = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/control_mixins/mx.js');
|
|
39
|
+
module.exports = jsgui;
|
package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-db06f132533706f4a0163b8c.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const jsgui = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/html-core/html-core.js');
|
|
2
|
+
jsgui.Router = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/router/router.js');
|
|
3
|
+
jsgui.Resource = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/resource.js');
|
|
4
|
+
jsgui.Resource_Pool = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/pool.js');
|
|
5
|
+
jsgui.Resource.Data_KV = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/data-kv-resource.js');
|
|
6
|
+
jsgui.Resource.Data_Transform = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/data-transform-resource.js');
|
|
7
|
+
jsgui.Resource.Compilation = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/compilation-resource.js');
|
|
8
|
+
jsgui.Resource.Compiler = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/compiler-resource.js');
|
|
9
|
+
jsgui.gfx = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/node_modules/jsgui3-gfx-core/core/gfx-core.js');
|
|
10
|
+
jsgui.Resource.load_compiler = (name, jsfn, options) => {
|
|
11
|
+
const compiler_name = name;
|
|
12
|
+
const compiler_fn = jsfn;
|
|
13
|
+
const compiler_options = options || {};
|
|
14
|
+
if (typeof compiler_name !== 'string' || compiler_name.length === 0) {
|
|
15
|
+
throw new Error('Resource.load_compiler(name, fn, options) requires a non-empty string name');
|
|
16
|
+
}
|
|
17
|
+
if (typeof compiler_fn !== 'function') {
|
|
18
|
+
throw new Error('Resource.load_compiler(name, fn, options) requires a function compiler implementation');
|
|
19
|
+
}
|
|
20
|
+
const compiler_resource = new jsgui.Resource.Compiler({ name: compiler_name });
|
|
21
|
+
compiler_resource.transform = (input, transform_options = {}) => {
|
|
22
|
+
const merged_options = Object.assign({}, compiler_options, transform_options);
|
|
23
|
+
return compiler_fn(input, merged_options);
|
|
24
|
+
};
|
|
25
|
+
jsgui.Resource.compilers = jsgui.Resource.compilers || {};
|
|
26
|
+
jsgui.Resource.compilers[compiler_name] = compiler_resource;
|
|
27
|
+
const pool = compiler_options.pool || compiler_options.resource_pool;
|
|
28
|
+
if (pool && typeof pool.add === 'function') {
|
|
29
|
+
pool.add(compiler_resource);
|
|
30
|
+
}
|
|
31
|
+
return compiler_resource;
|
|
32
|
+
};
|
|
33
|
+
jsgui.controls = jsgui.controls || {};
|
|
34
|
+
Object.assign(jsgui.controls, {
|
|
35
|
+
|
|
36
|
+
});
|
|
37
|
+
Object.assign(jsgui, jsgui.controls);
|
|
38
|
+
jsgui.mixins = jsgui.mx = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/control_mixins/mx.js');
|
|
39
|
+
module.exports = jsgui;
|
package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-f660f40d78b135fc8560a862.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const jsgui = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/html-core/html-core.js');
|
|
2
|
+
jsgui.Router = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/router/router.js');
|
|
3
|
+
jsgui.Resource = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/resource.js');
|
|
4
|
+
jsgui.Resource_Pool = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/pool.js');
|
|
5
|
+
jsgui.Resource.Data_KV = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/data-kv-resource.js');
|
|
6
|
+
jsgui.Resource.Data_Transform = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/data-transform-resource.js');
|
|
7
|
+
jsgui.Resource.Compilation = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/compilation-resource.js');
|
|
8
|
+
jsgui.Resource.Compiler = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/compiler-resource.js');
|
|
9
|
+
jsgui.gfx = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/node_modules/jsgui3-gfx-core/core/gfx-core.js');
|
|
10
|
+
jsgui.Resource.load_compiler = (name, jsfn, options) => {
|
|
11
|
+
const compiler_name = name;
|
|
12
|
+
const compiler_fn = jsfn;
|
|
13
|
+
const compiler_options = options || {};
|
|
14
|
+
if (typeof compiler_name !== 'string' || compiler_name.length === 0) {
|
|
15
|
+
throw new Error('Resource.load_compiler(name, fn, options) requires a non-empty string name');
|
|
16
|
+
}
|
|
17
|
+
if (typeof compiler_fn !== 'function') {
|
|
18
|
+
throw new Error('Resource.load_compiler(name, fn, options) requires a function compiler implementation');
|
|
19
|
+
}
|
|
20
|
+
const compiler_resource = new jsgui.Resource.Compiler({ name: compiler_name });
|
|
21
|
+
compiler_resource.transform = (input, transform_options = {}) => {
|
|
22
|
+
const merged_options = Object.assign({}, compiler_options, transform_options);
|
|
23
|
+
return compiler_fn(input, merged_options);
|
|
24
|
+
};
|
|
25
|
+
jsgui.Resource.compilers = jsgui.Resource.compilers || {};
|
|
26
|
+
jsgui.Resource.compilers[compiler_name] = compiler_resource;
|
|
27
|
+
const pool = compiler_options.pool || compiler_options.resource_pool;
|
|
28
|
+
if (pool && typeof pool.add === 'function') {
|
|
29
|
+
pool.add(compiler_resource);
|
|
30
|
+
}
|
|
31
|
+
return compiler_resource;
|
|
32
|
+
};
|
|
33
|
+
jsgui.controls = jsgui.controls || {};
|
|
34
|
+
Object.assign(jsgui.controls, {
|
|
35
|
+
|
|
36
|
+
});
|
|
37
|
+
Object.assign(jsgui, jsgui.controls);
|
|
38
|
+
jsgui.mixins = jsgui.mx = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/control_mixins/mx.js');
|
|
39
|
+
module.exports = jsgui;
|
package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-f9dee4ec18a96e09bee06bae.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const jsgui = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/html-core/html-core.js');
|
|
2
|
+
jsgui.Router = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/router/router.js');
|
|
3
|
+
jsgui.Resource = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/resource.js');
|
|
4
|
+
jsgui.Resource_Pool = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/pool.js');
|
|
5
|
+
jsgui.Resource.Data_KV = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/data-kv-resource.js');
|
|
6
|
+
jsgui.Resource.Data_Transform = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/data-transform-resource.js');
|
|
7
|
+
jsgui.Resource.Compilation = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/compilation-resource.js');
|
|
8
|
+
jsgui.Resource.Compiler = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/resource/compiler-resource.js');
|
|
9
|
+
jsgui.gfx = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/node_modules/jsgui3-gfx-core/core/gfx-core.js');
|
|
10
|
+
jsgui.Resource.load_compiler = (name, jsfn, options) => {
|
|
11
|
+
const compiler_name = name;
|
|
12
|
+
const compiler_fn = jsfn;
|
|
13
|
+
const compiler_options = options || {};
|
|
14
|
+
if (typeof compiler_name !== 'string' || compiler_name.length === 0) {
|
|
15
|
+
throw new Error('Resource.load_compiler(name, fn, options) requires a non-empty string name');
|
|
16
|
+
}
|
|
17
|
+
if (typeof compiler_fn !== 'function') {
|
|
18
|
+
throw new Error('Resource.load_compiler(name, fn, options) requires a function compiler implementation');
|
|
19
|
+
}
|
|
20
|
+
const compiler_resource = new jsgui.Resource.Compiler({ name: compiler_name });
|
|
21
|
+
compiler_resource.transform = (input, transform_options = {}) => {
|
|
22
|
+
const merged_options = Object.assign({}, compiler_options, transform_options);
|
|
23
|
+
return compiler_fn(input, merged_options);
|
|
24
|
+
};
|
|
25
|
+
jsgui.Resource.compilers = jsgui.Resource.compilers || {};
|
|
26
|
+
jsgui.Resource.compilers[compiler_name] = compiler_resource;
|
|
27
|
+
const pool = compiler_options.pool || compiler_options.resource_pool;
|
|
28
|
+
if (pool && typeof pool.add === 'function') {
|
|
29
|
+
pool.add(compiler_resource);
|
|
30
|
+
}
|
|
31
|
+
return compiler_resource;
|
|
32
|
+
};
|
|
33
|
+
jsgui.controls = jsgui.controls || {};
|
|
34
|
+
Object.assign(jsgui.controls, {
|
|
35
|
+
Window: require('/mnt/c/Users/james/Documents/repos/jsgui3-html/controls/organised/1-standard/6-layout/window')
|
|
36
|
+
});
|
|
37
|
+
Object.assign(jsgui, jsgui.controls);
|
|
38
|
+
jsgui.mixins = jsgui.mx = require('/mnt/c/Users/james/Documents/repos/jsgui3-html/control_mixins/mx.js');
|
|
39
|
+
module.exports = jsgui;
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ This is the primary entry point for understanding the JSGUI3 Server project. Rea
|
|
|
8
8
|
- You're looking for quick start guides and basic usage examples
|
|
9
9
|
- You need to understand the project's capabilities and limitations
|
|
10
10
|
|
|
11
|
-
**Note:** For detailed API documentation, see [docs/comprehensive-documentation.md](docs/comprehensive-documentation.md). For advanced server API design, see [docs/simple-server-api-design.md](docs/simple-server-api-design.md).
|
|
11
|
+
**Note:** For detailed API documentation, see [docs/comprehensive-documentation.md](docs/comprehensive-documentation.md). For advanced server API design, see [docs/simple-server-api-design.md](docs/simple-server-api-design.md). For dense internals focused on startup, resources, SSE, and E2E verification, see [docs/core/jsgui3-server-core-book/00-table-of-contents.md](docs/core/jsgui3-server-core-book/00-table-of-contents.md). For deep bundling research and lightweight-bundle strategy, see [docs/books/jsgui3-bundling-research-book/README.md](docs/books/jsgui3-bundling-research-book/README.md).
|
|
12
12
|
|
|
13
13
|
# Jsgui3 Server
|
|
14
14
|
|
|
@@ -72,6 +72,66 @@ Server.serve({
|
|
|
72
72
|
});
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
+
### Managed Resources (In-Process, Direct Process, Remote Process)
|
|
76
|
+
|
|
77
|
+
```javascript
|
|
78
|
+
const Server = require('jsgui3-server');
|
|
79
|
+
const { Resource } = require('jsgui3-server');
|
|
80
|
+
|
|
81
|
+
class In_Process_Cache_Resource extends Resource {
|
|
82
|
+
constructor(spec = {}) {
|
|
83
|
+
super(spec);
|
|
84
|
+
this.cache = new Map();
|
|
85
|
+
}
|
|
86
|
+
start(callback) { callback(null, true); }
|
|
87
|
+
stop(callback) { this.cache.clear(); callback(null, true); }
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const server = await Server.serve({
|
|
91
|
+
port: 3000,
|
|
92
|
+
api: {
|
|
93
|
+
'resources/summary': () => server.resource_pool.summary
|
|
94
|
+
},
|
|
95
|
+
resources: {
|
|
96
|
+
// Existing in-process resource instance
|
|
97
|
+
cache: new In_Process_Cache_Resource({ name: 'cache' }),
|
|
98
|
+
|
|
99
|
+
// Local child process (default process_manager is direct)
|
|
100
|
+
worker_direct: {
|
|
101
|
+
type: 'process',
|
|
102
|
+
command: process.execPath,
|
|
103
|
+
args: ['worker.js'],
|
|
104
|
+
autoRestart: true
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
// Local process managed by PM2 (pm2Path is optional)
|
|
108
|
+
worker_pm2: {
|
|
109
|
+
type: 'process',
|
|
110
|
+
processManager: {
|
|
111
|
+
type: 'pm2'
|
|
112
|
+
},
|
|
113
|
+
command: process.execPath,
|
|
114
|
+
args: ['worker.js']
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
// Remote process controlled over HTTP
|
|
118
|
+
remote_worker: {
|
|
119
|
+
type: 'remote',
|
|
120
|
+
host: '127.0.0.1',
|
|
121
|
+
port: 3400
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
events: true // creates /events SSE endpoint and forwards pool resource lifecycle events
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
All process-style resources expose a consistent API:
|
|
129
|
+
- `start()`
|
|
130
|
+
- `stop()`
|
|
131
|
+
- `restart()`
|
|
132
|
+
- `status` (includes `state`, `pid`, `uptime`, `restartCount`, `lastHealthCheck`, `memoryUsage`, `processManager`)
|
|
133
|
+
- `get_abstract()`
|
|
134
|
+
|
|
75
135
|
### Real-time SSE Streams
|
|
76
136
|
|
|
77
137
|
```javascript
|
|
@@ -83,11 +143,29 @@ const obs = observable(next => {
|
|
|
83
143
|
|
|
84
144
|
// Start server and publish stream
|
|
85
145
|
const server = await Server.serve(MyControl);
|
|
86
|
-
|
|
87
|
-
//
|
|
146
|
+
|
|
147
|
+
// Simple name - auto-prefixes /api/
|
|
148
|
+
server.publish_observable('stream', obs);
|
|
149
|
+
// Server publishes SSE stream at http://localhost:8080/api/stream
|
|
150
|
+
|
|
151
|
+
// Or use full route path for custom routes
|
|
152
|
+
server.publish_observable('/custom/events', obs);
|
|
153
|
+
// Server publishes SSE stream at http://localhost:8080/custom/events
|
|
154
|
+
|
|
88
155
|
// Client connects via EventSource or Remote_Observable
|
|
89
156
|
```
|
|
90
157
|
|
|
158
|
+
### General SSE Publisher
|
|
159
|
+
|
|
160
|
+
```javascript
|
|
161
|
+
const HTTP_SSE_Publisher = require('jsgui3-server/publishers/http-sse-publisher');
|
|
162
|
+
|
|
163
|
+
const sse_publisher = new HTTP_SSE_Publisher({ name: 'events' });
|
|
164
|
+
server.server_router.set_route('/events', sse_publisher, sse_publisher.handle_http);
|
|
165
|
+
|
|
166
|
+
sse_publisher.broadcast('resource_update', { running: 3, total: 5 });
|
|
167
|
+
```
|
|
168
|
+
|
|
91
169
|
> **Note:** The new `Server.serve()` API is the recommended approach for most use cases. See [Simple Server API Design](docs/simple-server-api-design.md) for complete documentation and advanced features.
|
|
92
170
|
|
|
93
171
|
## Architecture Overview
|
|
@@ -909,11 +987,15 @@ Minimal example:
|
|
|
909
987
|
```javascript
|
|
910
988
|
// Inside your server bootstrap (after constructing Server)
|
|
911
989
|
server.on('ready', () => {
|
|
990
|
+
// Simple name - auto-prefixes /api/
|
|
912
991
|
// Returns text/plain at GET/POST /api/hello
|
|
913
992
|
server.publish('hello', name => `Hello ${name || 'world'}`);
|
|
914
993
|
|
|
915
994
|
// Returns application/json at GET/POST /api/sum
|
|
916
995
|
server.publish('sum', ({ a, b }) => ({ sum: a + b }));
|
|
996
|
+
|
|
997
|
+
// Full route path for custom routes (no auto-prefix)
|
|
998
|
+
server.publish('/custom/endpoint', () => ({ custom: true }));
|
|
917
999
|
});
|
|
918
1000
|
```
|
|
919
1001
|
|
package/admin-ui/client.js
CHANGED
|
@@ -50,9 +50,9 @@ class Admin_Page extends Active_HTML_Document {
|
|
|
50
50
|
top_bar.add(this.page_title);
|
|
51
51
|
|
|
52
52
|
// Content Panel
|
|
53
|
-
const
|
|
54
|
-
main.add(
|
|
55
|
-
this.
|
|
53
|
+
const content_panel = new controls.div({ context, class: 'admin-content' });
|
|
54
|
+
main.add(content_panel);
|
|
55
|
+
this.content_panel = content_panel;
|
|
56
56
|
|
|
57
57
|
// Default content (Overview)
|
|
58
58
|
this._render_overview();
|
|
@@ -75,15 +75,15 @@ class Admin_Page extends Active_HTML_Document {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
_render_overview() {
|
|
78
|
-
// Clear main content area (
|
|
79
|
-
if (this.
|
|
80
|
-
this.
|
|
81
|
-
}
|
|
78
|
+
// Clear main content area (content_panel is the admin-content div)
|
|
79
|
+
if (this.content_panel && this.content_panel.content && typeof this.content_panel.content.clear === 'function') {
|
|
80
|
+
this.content_panel.content.clear();
|
|
81
|
+
}
|
|
82
82
|
|
|
83
83
|
const welcome = new controls.div({ context: this.context, class: 'welcome-card' });
|
|
84
84
|
welcome.add(new controls.h3({ context: this.context }).add('Welcome directly to jsgui3-server Admin'));
|
|
85
85
|
welcome.add(new controls.p({ context: this.context }).add('Select a resource from the sidebar to inspect.'));
|
|
86
|
-
this.
|
|
86
|
+
this.content_panel.add(welcome);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
activate() {
|
package/dev-status.svg
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 850" style="background:#1e1e2e; font-family: 'Segoe UI', sans-serif; color: #cdd6f4;">
|
|
2
|
+
<!-- Definitions for gradients and shadows -->
|
|
3
|
+
<defs>
|
|
4
|
+
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
|
|
5
|
+
<feDropShadow dx="3" dy="3" stdDeviation="4" flood-color="#000000" flood-opacity="0.5"/>
|
|
6
|
+
</filter>
|
|
7
|
+
<linearGradient id="grad-server" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
8
|
+
<stop offset="0%" style="stop-color:#313244;stop-opacity:1" />
|
|
9
|
+
<stop offset="100%" style="stop-color:#45475a;stop-opacity:1" />
|
|
10
|
+
</linearGradient>
|
|
11
|
+
<linearGradient id="grad-client" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
12
|
+
<stop offset="0%" style="stop-color:#181825;stop-opacity:1" />
|
|
13
|
+
<stop offset="100%" style="stop-color:#1e1e2e;stop-opacity:1" />
|
|
14
|
+
</linearGradient>
|
|
15
|
+
<linearGradient id="grad-success" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
16
|
+
<stop offset="0%" style="stop-color:#a6e3a1;stop-opacity:0.2" />
|
|
17
|
+
<stop offset="100%" style="stop-color:#a6e3a1;stop-opacity:0.1" />
|
|
18
|
+
</linearGradient>
|
|
19
|
+
<marker id="arrow" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
|
|
20
|
+
<path d="M0,0 L0,6 L9,3 z" fill="#89b4fa" />
|
|
21
|
+
</marker>
|
|
22
|
+
</defs>
|
|
23
|
+
|
|
24
|
+
<!-- Title -->
|
|
25
|
+
<text x="50" y="50" fill="#cdd6f4" font-size="32" font-weight="bold">jsgui3-server: Dev Status & Architecture</text>
|
|
26
|
+
<text x="50" y="80" fill="#a6adc8" font-size="16">Admin UI • Auto-Observables • Defensive Programming • Server Lifecycle</text>
|
|
27
|
+
|
|
28
|
+
<!-- Areas -->
|
|
29
|
+
<rect x="50" y="110" width="500" height="700" rx="15" fill="url(#grad-server)" stroke="#585b70" stroke-width="2" />
|
|
30
|
+
<text x="70" y="140" fill="#fab387" font-size="24" font-weight="bold">Server Side (Node.js)</text>
|
|
31
|
+
|
|
32
|
+
<rect x="650" y="110" width="500" height="700" rx="15" fill="url(#grad-client)" stroke="#585b70" stroke-width="2" />
|
|
33
|
+
<text x="670" y="140" fill="#89b4fa" font-size="24" font-weight="bold">Client Side (Browser)</text>
|
|
34
|
+
|
|
35
|
+
<!-- Server Components -->
|
|
36
|
+
|
|
37
|
+
<!-- Server Lifecycle Box -->
|
|
38
|
+
<g transform="translate(80, 180)">
|
|
39
|
+
<rect width="440" height="140" rx="8" fill="#313244" stroke="#f38ba8" stroke-width="2" stroke-dasharray="5,5" filter="url(#shadow)" />
|
|
40
|
+
<text x="15" y="30" fill="#f38ba8" font-size="18" font-weight="bold">Lifecycle Fixes</text>
|
|
41
|
+
|
|
42
|
+
<g transform="translate(20, 50)">
|
|
43
|
+
<circle cx="10" cy="10" r="5" fill="#f38ba8" />
|
|
44
|
+
<text x="25" y="15" fill="#cdd6f4" font-size="14">1. _started Guard (Prevents double start)</text>
|
|
45
|
+
</g>
|
|
46
|
+
<g transform="translate(20, 80)">
|
|
47
|
+
<circle cx="10" cy="10" r="5" fill="#f38ba8" />
|
|
48
|
+
<text x="25" y="15" fill="#cdd6f4" font-size="14">2. Split Events: 'ready' vs 'listening'</text>
|
|
49
|
+
</g>
|
|
50
|
+
<g transform="translate(20, 110)">
|
|
51
|
+
<text x="25" y="15" fill="#a6adc8" font-size="12" font-style="italic">Fixed EADDRINUSE crash root cause</text>
|
|
52
|
+
</g>
|
|
53
|
+
</g>
|
|
54
|
+
|
|
55
|
+
<!-- Admin Module -->
|
|
56
|
+
<g transform="translate(80, 350)">
|
|
57
|
+
<rect width="200" height="120" rx="8" fill="#45475a" stroke="#89b4fa" stroke-width="2" filter="url(#shadow)" />
|
|
58
|
+
<text x="50" y="30" fill="#89b4fa" font-size="18" font-weight="bold">Admin_Module</text>
|
|
59
|
+
<line x1="10" y1="40" x2="190" y2="40" stroke="#585b70" />
|
|
60
|
+
<text x="15" y="65" fill="#cdd6f4" font-size="14">GET /api/admin/resources</text>
|
|
61
|
+
<text x="15" y="90" fill="#cdd6f4" font-size="14">GET /api/admin/observables</text>
|
|
62
|
+
</g>
|
|
63
|
+
|
|
64
|
+
<!-- Publishers -->
|
|
65
|
+
<g transform="translate(320, 350)">
|
|
66
|
+
<rect width="200" height="120" rx="8" fill="#45475a" stroke="#a6e3a1" stroke-width="2" filter="url(#shadow)" />
|
|
67
|
+
<text x="30" y="30" fill="#a6e3a1" font-size="18" font-weight="bold">Publishers</text>
|
|
68
|
+
<line x1="10" y1="40" x2="190" y2="40" stroke="#585b70" />
|
|
69
|
+
<text x="15" y="65" fill="#cdd6f4" font-size="14">HTTP_Webpage_Publisher</text>
|
|
70
|
+
<text x="15" y="90" fill="#cdd6f4" font-size="14">HTTP_Observable_Publisher</text>
|
|
71
|
+
</g>
|
|
72
|
+
|
|
73
|
+
<!-- Defensive Layers -->
|
|
74
|
+
<g transform="translate(80, 500)">
|
|
75
|
+
<rect width="440" height="100" rx="8" fill="url(#grad-success)" stroke="#a6e3a1" stroke-width="1" />
|
|
76
|
+
<text x="15" y="30" fill="#a6e3a1" font-size="18" font-weight="bold">Defensive Coding Layers</text>
|
|
77
|
+
<text x="20" y="60" fill="#cdd6f4" font-size="14">• Resource_Pool.add(undefined) → Warn & Return</text>
|
|
78
|
+
<text x="20" y="80" fill="#cdd6f4" font-size="14">• Bundler Failures → Fallback Empty Bundle</text>
|
|
79
|
+
</g>
|
|
80
|
+
|
|
81
|
+
<!-- Bundler -->
|
|
82
|
+
<g transform="translate(80, 630)">
|
|
83
|
+
<rect width="440" height="60" rx="8" fill="#313244" stroke="#fab387" stroke-width="2" />
|
|
84
|
+
<text x="15" y="35" fill="#fab387" font-size="18" font-weight="bold">Bundler (esbuild)</text>
|
|
85
|
+
<text x="180" y="35" fill="#cdd6f4" font-size="14">Fixed: npm link jsgui3-html</text>
|
|
86
|
+
</g>
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
<!-- Client Components -->
|
|
90
|
+
|
|
91
|
+
<!-- Admin Page -->
|
|
92
|
+
<g transform="translate(680, 250)">
|
|
93
|
+
<rect width="440" height="180" rx="8" fill="#313244" stroke="#89b4fa" stroke-width="2" filter="url(#shadow)" />
|
|
94
|
+
<text x="15" y="30" fill="#89b4fa" font-size="18" font-weight="bold">Admin_Page (Client)</text>
|
|
95
|
+
<line x1="10" y1="40" x2="430" y2="40" stroke="#585b70" />
|
|
96
|
+
|
|
97
|
+
<!-- Child Controls -->
|
|
98
|
+
<g transform="translate(20, 60)">
|
|
99
|
+
<rect width="180" height="40" rx="4" fill="#45475a" stroke="#cba6f7" stroke-width="1" />
|
|
100
|
+
<text x="35" y="25" fill="#cba6f7" font-size="14">Resource_List</text>
|
|
101
|
+
</g>
|
|
102
|
+
|
|
103
|
+
<g transform="translate(220, 60)">
|
|
104
|
+
<rect width="180" height="40" rx="4" fill="#45475a" stroke="#cba6f7" stroke-width="1" />
|
|
105
|
+
<text x="25" y="25" fill="#cba6f7" font-size="14">Observables_List</text>
|
|
106
|
+
</g>
|
|
107
|
+
|
|
108
|
+
<g transform="translate(120, 120)">
|
|
109
|
+
<rect width="200" height="40" rx="4" fill="#45475a" stroke="#f9e2af" stroke-width="1" />
|
|
110
|
+
<text x="30" y="25" fill="#f9e2af" font-size="14">Auto_Observable_UI</text>
|
|
111
|
+
</g>
|
|
112
|
+
</g>
|
|
113
|
+
|
|
114
|
+
<!-- Data Flow Arrows -->
|
|
115
|
+
|
|
116
|
+
<!-- Route Info -->
|
|
117
|
+
<path d="M 280 410 L 680 300" stroke="#89b4fa" stroke-width="2" stroke-dasharray="5,5" fill="none" marker-end="url(#arrow)" />
|
|
118
|
+
<rect x="420" y="330" width="120" height="25" rx="4" fill="#1e1e2e" stroke="#89b4fa" />
|
|
119
|
+
<text x="430" y="347" fill="#89b4fa" font-size="12">JSON Data</text>
|
|
120
|
+
|
|
121
|
+
<!-- Observable Stream -->
|
|
122
|
+
<path d="M 430 470 L 800 390" stroke="#a6e3a1" stroke-width="2" fill="none" marker-end="url(#arrow)" />
|
|
123
|
+
<rect x="560" y="440" width="100" height="25" rx="4" fill="#1e1e2e" stroke="#a6e3a1" />
|
|
124
|
+
<text x="575" y="457" fill="#a6e3a1" font-size="12">SSE Steam</text>
|
|
125
|
+
|
|
126
|
+
<!-- Legend -->
|
|
127
|
+
<g transform="translate(900, 750)">
|
|
128
|
+
<text x="0" y="0" fill="#a6adc8" font-size="14" font-weight="bold">Legend</text>
|
|
129
|
+
<rect x="0" y="10" width="15" height="15" fill="#313244" stroke="#f38ba8" />
|
|
130
|
+
<text x="25" y="23" fill="#cdd6f4" font-size="12">Lifecycle Code</text>
|
|
131
|
+
|
|
132
|
+
<rect x="0" y="35" width="15" height="15" fill="#313244" stroke="#89b4fa" />
|
|
133
|
+
<text x="25" y="48" fill="#cdd6f4" font-size="12">UI / Route Component</text>
|
|
134
|
+
|
|
135
|
+
<rect x="0" y="60" width="15" height="15" fill="#313244" stroke="#a6e3a1" />
|
|
136
|
+
<text x="25" y="73" fill="#cdd6f4" font-size="12">Observable / Defensive</text>
|
|
137
|
+
</g>
|
|
138
|
+
|
|
139
|
+
</svg>
|