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.
- 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 +213 -0
- package/admin-ui/server.js +104 -0
- package/client/controls/auto-observable.js +207 -0
- package/dev-status.svg +139 -0
- package/docs/api-reference.md +301 -43
- package/docs/books/admin-ui/01-introduction.md +32 -0
- package/docs/books/admin-ui/02-architecture.md +92 -0
- package/docs/books/admin-ui/03-controls.md +194 -0
- package/docs/books/admin-ui/04-implementation-plan.md +62 -0
- package/docs/books/admin-ui/README.md +26 -0
- package/docs/books/jsgui3-bundling-research-book/00-table-of-contents.md +35 -0
- package/docs/books/jsgui3-bundling-research-book/01-pipeline-and-runtime-semantics.md +34 -0
- package/docs/books/jsgui3-bundling-research-book/02-javascript-bundling-core.md +36 -0
- package/docs/books/jsgui3-bundling-research-book/03-style-extraction-and-css-compilation.md +35 -0
- package/docs/books/jsgui3-bundling-research-book/04-static-publishing-and-delivery.md +39 -0
- package/docs/books/jsgui3-bundling-research-book/05-current-limits-and-size-bloat-vectors.md +25 -0
- package/docs/books/jsgui3-bundling-research-book/06-unused-module-elimination-strategy.md +77 -0
- package/docs/books/jsgui3-bundling-research-book/07-jsgui3-html-control-and-mixin-pruning.md +63 -0
- package/docs/books/jsgui3-bundling-research-book/08-test-and-verification-methodology.md +43 -0
- package/docs/books/jsgui3-bundling-research-book/09-roadmap-and-rollout.md +42 -0
- package/docs/books/jsgui3-bundling-research-book/10-further-research-strategies-and-upgrades.md +211 -0
- package/docs/books/jsgui3-bundling-research-book/README.md +35 -0
- package/docs/bundling-system-deep-dive.md +9 -4
- package/docs/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/client.js +125 -0
- package/examples/controls/19) window, auto observable ui/server.js +73 -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 +14 -4
- 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-observable-publisher.js +8 -0
- package/publishers/http-sse-publisher.js +341 -0
- package/publishers/http-webpage-publisher.js +13 -3
- package/publishers/http-webpageorsite-publisher.js +18 -0
- package/resources/process-resource.js +950 -0
- package/resources/processors/bundlers/js/esbuild/Advanced_JS_Bundler_Using_ESBuild.js +164 -46
- 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 +161 -16
- 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
|
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
const jsgui = require('jsgui3-client');
|
|
2
|
+
const { controls, Control, mixins } = jsgui;
|
|
3
|
+
const Active_HTML_Document = require('../controls/Active_HTML_Document');
|
|
4
|
+
|
|
5
|
+
class Admin_Page extends Active_HTML_Document {
|
|
6
|
+
constructor(spec = {}) {
|
|
7
|
+
spec.__type_name = spec.__type_name || 'admin_page';
|
|
8
|
+
super(spec);
|
|
9
|
+
const { context } = this;
|
|
10
|
+
|
|
11
|
+
if (typeof this.body.add_class === 'function') {
|
|
12
|
+
this.body.add_class('admin-page');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const compose = () => {
|
|
16
|
+
// Sidebar
|
|
17
|
+
const sidebar = new controls.div({ context, class: 'admin-sidebar' });
|
|
18
|
+
this.body.add(sidebar);
|
|
19
|
+
this.sidebar = sidebar;
|
|
20
|
+
|
|
21
|
+
// Sidebar Header
|
|
22
|
+
const brand = new controls.div({ context, class: 'admin-brand' });
|
|
23
|
+
brand.add(new controls.span({ context, class: 'brand-icon' }).add('⚙️'));
|
|
24
|
+
brand.add(new controls.span({ context, class: 'brand-text' }).add('jsgui3 Admin'));
|
|
25
|
+
sidebar.add(brand);
|
|
26
|
+
|
|
27
|
+
// Menu Container (Placeholder for Resource_List and Observables_List)
|
|
28
|
+
const menu = new controls.div({ context, class: 'admin-menu' });
|
|
29
|
+
sidebar.add(menu);
|
|
30
|
+
this.menu = menu;
|
|
31
|
+
|
|
32
|
+
this._add_menu_item('Overview', 'overview', true);
|
|
33
|
+
this._add_menu_item('Resources', 'resources');
|
|
34
|
+
this._add_menu_item('Observables', 'observables');
|
|
35
|
+
this._add_menu_item('Settings', 'settings');
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
// Main Content Area
|
|
39
|
+
const main = new controls.div({ context, class: 'admin-main' });
|
|
40
|
+
this.body.add(main);
|
|
41
|
+
this.main = main;
|
|
42
|
+
|
|
43
|
+
// Top Bar
|
|
44
|
+
const top_bar = new controls.div({ context, class: 'admin-top-bar' });
|
|
45
|
+
main.add(top_bar);
|
|
46
|
+
|
|
47
|
+
// Breadcrumbs / Title
|
|
48
|
+
this.page_title = new controls.h2({ context, class: 'page-title' });
|
|
49
|
+
this.page_title.add('Overview');
|
|
50
|
+
top_bar.add(this.page_title);
|
|
51
|
+
|
|
52
|
+
// Content Panel
|
|
53
|
+
const content_panel = new controls.div({ context, class: 'admin-content' });
|
|
54
|
+
main.add(content_panel);
|
|
55
|
+
this.content_panel = content_panel;
|
|
56
|
+
|
|
57
|
+
// Default content (Overview)
|
|
58
|
+
this._render_overview();
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
if (!spec.el) {
|
|
62
|
+
compose();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
_add_menu_item(label, id, active = false) {
|
|
67
|
+
const item = new controls.div({
|
|
68
|
+
context: this.context,
|
|
69
|
+
class: `menu-item ${active ? 'active' : ''}`
|
|
70
|
+
});
|
|
71
|
+
item.dom.attributes['data-id'] = id;
|
|
72
|
+
item.add(label);
|
|
73
|
+
this.menu.add(item);
|
|
74
|
+
return item;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
_render_overview() {
|
|
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
|
+
|
|
83
|
+
const welcome = new controls.div({ context: this.context, class: 'welcome-card' });
|
|
84
|
+
welcome.add(new controls.h3({ context: this.context }).add('Welcome directly to jsgui3-server Admin'));
|
|
85
|
+
welcome.add(new controls.p({ context: this.context }).add('Select a resource from the sidebar to inspect.'));
|
|
86
|
+
this.content_panel.add(welcome);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
activate() {
|
|
90
|
+
if (!this.__active) {
|
|
91
|
+
super.activate();
|
|
92
|
+
|
|
93
|
+
// Handle menu clicks
|
|
94
|
+
const menu_items = document.querySelectorAll('.menu-item');
|
|
95
|
+
menu_items.forEach(el => {
|
|
96
|
+
el.addEventListener('click', () => {
|
|
97
|
+
// Update Active State
|
|
98
|
+
menu_items.forEach(i => i.classList.remove('active'));
|
|
99
|
+
el.classList.add('active');
|
|
100
|
+
|
|
101
|
+
// Update Title
|
|
102
|
+
const id = el.getAttribute('data-id');
|
|
103
|
+
const label = el.innerText;
|
|
104
|
+
document.querySelector('.page-title').innerText = label;
|
|
105
|
+
|
|
106
|
+
// Placeholder navigation logic
|
|
107
|
+
console.log('Navigate to:', id);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
Admin_Page.css = `
|
|
115
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
116
|
+
body {
|
|
117
|
+
background: #1a1a2e;
|
|
118
|
+
color: #e0e0e0;
|
|
119
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
120
|
+
height: 100vh;
|
|
121
|
+
overflow: hidden;
|
|
122
|
+
}
|
|
123
|
+
.admin-page {
|
|
124
|
+
display: grid;
|
|
125
|
+
grid-template-columns: 260px 1fr;
|
|
126
|
+
height: 100%;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* Sidebar */
|
|
130
|
+
.admin-sidebar {
|
|
131
|
+
background: #16213e;
|
|
132
|
+
border-right: 1px solid #2a2a4a;
|
|
133
|
+
display: flex;
|
|
134
|
+
flex-direction: column;
|
|
135
|
+
}
|
|
136
|
+
.admin-brand {
|
|
137
|
+
padding: 20px;
|
|
138
|
+
font-size: 1.2rem;
|
|
139
|
+
font-weight: bold;
|
|
140
|
+
color: #fff;
|
|
141
|
+
border-bottom: 1px solid #2a2a4a;
|
|
142
|
+
display: flex;
|
|
143
|
+
align-items: center;
|
|
144
|
+
gap: 10px;
|
|
145
|
+
}
|
|
146
|
+
.brand-icon { filter: drop-shadow(0 0 5px rgba(255,255,255,0.3)); }
|
|
147
|
+
|
|
148
|
+
.admin-menu {
|
|
149
|
+
flex: 1;
|
|
150
|
+
padding: 20px 0;
|
|
151
|
+
overflow-y: auto;
|
|
152
|
+
}
|
|
153
|
+
.menu-item {
|
|
154
|
+
padding: 12px 24px;
|
|
155
|
+
cursor: pointer;
|
|
156
|
+
border-left: 3px solid transparent;
|
|
157
|
+
transition: all 0.2s;
|
|
158
|
+
color: #a0a0b0;
|
|
159
|
+
}
|
|
160
|
+
.menu-item:hover {
|
|
161
|
+
background: rgba(255,255,255,0.05);
|
|
162
|
+
color: #fff;
|
|
163
|
+
}
|
|
164
|
+
.menu-item.active {
|
|
165
|
+
background: rgba(79, 172, 254, 0.1);
|
|
166
|
+
color: #4facfe;
|
|
167
|
+
border-left-color: #4facfe;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* Main Area */
|
|
171
|
+
.admin-main {
|
|
172
|
+
display: flex;
|
|
173
|
+
flex-direction: column;
|
|
174
|
+
background: #1a1a2e;
|
|
175
|
+
}
|
|
176
|
+
.admin-top-bar {
|
|
177
|
+
height: 64px;
|
|
178
|
+
border-bottom: 1px solid #2a2a4a;
|
|
179
|
+
display: flex;
|
|
180
|
+
align-items: center;
|
|
181
|
+
padding: 0 30px;
|
|
182
|
+
background: #16213e;
|
|
183
|
+
}
|
|
184
|
+
.page-title {
|
|
185
|
+
font-size: 1.2rem;
|
|
186
|
+
font-weight: 500;
|
|
187
|
+
color: #fff;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.admin-content {
|
|
191
|
+
flex: 1;
|
|
192
|
+
overflow-y: auto;
|
|
193
|
+
padding: 30px;
|
|
194
|
+
position: relative;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/* Cards */
|
|
198
|
+
.welcome-card {
|
|
199
|
+
background: #2a2a4a;
|
|
200
|
+
padding: 40px;
|
|
201
|
+
border-radius: 12px;
|
|
202
|
+
text-align: center;
|
|
203
|
+
max-width: 600px;
|
|
204
|
+
margin: 40px auto;
|
|
205
|
+
border: 1px solid #3a3a5a;
|
|
206
|
+
box-shadow: 0 4px 20px rgba(0,0,0,0.2);
|
|
207
|
+
}
|
|
208
|
+
.welcome-card h3 { color: #fff; margin-bottom: 15px; }
|
|
209
|
+
.welcome-card p { color: #a0a0b0; }
|
|
210
|
+
`;
|
|
211
|
+
|
|
212
|
+
controls.Admin_Page = Admin_Page;
|
|
213
|
+
module.exports = jsgui;
|