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
|
@@ -7,11 +7,33 @@ const path = require('path');
|
|
|
7
7
|
const Core_JS_Non_Minifying_Bundler_Using_ESBuild = require('../resources/processors/bundlers/js/esbuild/Core_JS_Non_Minifying_Bundler_Using_ESBuild');
|
|
8
8
|
const Core_JS_Single_File_Minifying_Bundler_Using_ESBuild = require('../resources/processors/bundlers/js/esbuild/Core_JS_Single_File_Minifying_Bundler_Using_ESBuild');
|
|
9
9
|
const Advanced_JS_Bundler_Using_ESBuild = require('../resources/processors/bundlers/js/esbuild/Advanced_JS_Bundler_Using_ESBuild');
|
|
10
|
-
const Single_Control_Webpage_Server_Static_Compressed_Response_Buffers_Assigner = require('../publishers/helpers/assigners/static-compressed-response-buffers/Single_Control_Webpage_Server_Static_Compressed_Response_Buffers_Assigner');
|
|
11
|
-
const HTTP_Webpage_Publisher = require('../publishers/http-webpage-publisher');
|
|
12
|
-
const Server = require('../server');
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
const Single_Control_Webpage_Server_Static_Compressed_Response_Buffers_Assigner = require('../publishers/helpers/assigners/static-compressed-response-buffers/Single_Control_Webpage_Server_Static_Compressed_Response_Buffers_Assigner');
|
|
11
|
+
const HTTP_Webpage_Publisher = require('../publishers/http-webpage-publisher');
|
|
12
|
+
const Server = require('../server');
|
|
13
|
+
|
|
14
|
+
const await_observable = (observable) => {
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
let settled = false;
|
|
17
|
+
const settle_once = (settle_fn, value) => {
|
|
18
|
+
if (settled) return;
|
|
19
|
+
settled = true;
|
|
20
|
+
settle_fn(value);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
observable.on('error', (error) => settle_once(reject, error));
|
|
24
|
+
observable.on('next', (value) => settle_once(resolve, value));
|
|
25
|
+
observable.on('complete', (value) => settle_once(resolve, value));
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const close_server_instance = (server_instance) => {
|
|
30
|
+
if (!server_instance || typeof server_instance.close !== 'function') {
|
|
31
|
+
return Promise.resolve();
|
|
32
|
+
}
|
|
33
|
+
return new Promise((resolve) => server_instance.close(() => resolve()));
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
describe('Error Handling Tests', function() {
|
|
15
37
|
this.timeout(15000);
|
|
16
38
|
|
|
17
39
|
let testJsFile;
|
|
@@ -49,12 +71,12 @@ describe('Error Handling Tests', function() {
|
|
|
49
71
|
describe('Bundler Error Handling', function() {
|
|
50
72
|
describe('Core_JS_Non_Minifying_Bundler_Using_ESBuild', function() {
|
|
51
73
|
it('should handle invalid JavaScript syntax gracefully', async function() {
|
|
52
|
-
const bundler = new Core_JS_Non_Minifying_Bundler_Using_ESBuild();
|
|
53
|
-
|
|
54
|
-
try {
|
|
55
|
-
await bundler.bundle_js_string(invalidJsContent);
|
|
56
|
-
assert.fail('Should have thrown an error for invalid JavaScript');
|
|
57
|
-
} catch (error) {
|
|
74
|
+
const bundler = new Core_JS_Non_Minifying_Bundler_Using_ESBuild();
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
await await_observable(bundler.bundle_js_string(invalidJsContent));
|
|
78
|
+
assert.fail('Should have thrown an error for invalid JavaScript');
|
|
79
|
+
} catch (error) {
|
|
58
80
|
assert(error, 'Should throw an error for invalid JavaScript');
|
|
59
81
|
// ESBuild errors typically contain information about the syntax issue
|
|
60
82
|
assert(error.message || error.toString(), 'Error should have a message');
|
|
@@ -62,35 +84,35 @@ describe('Error Handling Tests', function() {
|
|
|
62
84
|
});
|
|
63
85
|
|
|
64
86
|
it('should handle non-existent files', async function() {
|
|
65
|
-
const bundler = new Core_JS_Non_Minifying_Bundler_Using_ESBuild();
|
|
66
|
-
|
|
67
|
-
try {
|
|
68
|
-
await bundler.bundle('/completely/nonexistent/file.js');
|
|
69
|
-
assert.fail('Should have thrown an error for non-existent file');
|
|
70
|
-
} catch (error) {
|
|
87
|
+
const bundler = new Core_JS_Non_Minifying_Bundler_Using_ESBuild();
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
await await_observable(bundler.bundle('/completely/nonexistent/file.js'));
|
|
91
|
+
assert.fail('Should have thrown an error for non-existent file');
|
|
92
|
+
} catch (error) {
|
|
71
93
|
assert(error, 'Should throw an error for non-existent file');
|
|
72
94
|
}
|
|
73
95
|
});
|
|
74
96
|
|
|
75
|
-
it('should handle empty JavaScript content', async function() {
|
|
76
|
-
const bundler = new Core_JS_Non_Minifying_Bundler_Using_ESBuild();
|
|
77
|
-
|
|
78
|
-
const result = await bundler.bundle_js_string('');
|
|
79
|
-
assert(result, 'Should handle empty content');
|
|
80
|
-
const bundle = result[0];
|
|
81
|
-
assert(bundle._arr[0], 'Should produce a bundle item');
|
|
82
|
-
});
|
|
97
|
+
it('should handle empty JavaScript content', async function() {
|
|
98
|
+
const bundler = new Core_JS_Non_Minifying_Bundler_Using_ESBuild();
|
|
99
|
+
|
|
100
|
+
const result = await await_observable(bundler.bundle_js_string(''));
|
|
101
|
+
assert(result, 'Should handle empty content');
|
|
102
|
+
const bundle = Array.isArray(result) ? result[0] : result;
|
|
103
|
+
assert(bundle._arr[0], 'Should produce a bundle item');
|
|
104
|
+
});
|
|
83
105
|
|
|
84
106
|
it('should handle very large JavaScript content', async function() {
|
|
85
107
|
const bundler = new Core_JS_Non_Minifying_Bundler_Using_ESBuild();
|
|
86
108
|
|
|
87
|
-
// Create a very large JS file (10MB)
|
|
88
|
-
const largeContent = 'console.log("test");\n'.repeat(100000);
|
|
89
|
-
|
|
90
|
-
try {
|
|
91
|
-
const result = await bundler.bundle_js_string(largeContent);
|
|
92
|
-
assert(result, 'Should handle large content');
|
|
93
|
-
} catch (error) {
|
|
109
|
+
// Create a very large JS file (10MB)
|
|
110
|
+
const largeContent = 'console.log("test");\n'.repeat(100000);
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
const result = await await_observable(bundler.bundle_js_string(largeContent));
|
|
114
|
+
assert(result, 'Should handle large content');
|
|
115
|
+
} catch (error) {
|
|
94
116
|
// Large files might cause memory issues, which is acceptable
|
|
95
117
|
assert(error, 'Large files may cause errors due to memory constraints');
|
|
96
118
|
}
|
|
@@ -103,12 +125,12 @@ describe('Error Handling Tests', function() {
|
|
|
103
125
|
const arrow = ( => {
|
|
104
126
|
console.log('invalid arrow function');
|
|
105
127
|
};
|
|
106
|
-
`;
|
|
107
|
-
|
|
108
|
-
try {
|
|
109
|
-
await bundler.bundle_js_string(es6ErrorContent);
|
|
110
|
-
assert.fail('Should have thrown an error for invalid ES6 syntax');
|
|
111
|
-
} catch (error) {
|
|
128
|
+
`;
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
await await_observable(bundler.bundle_js_string(es6ErrorContent));
|
|
132
|
+
assert.fail('Should have thrown an error for invalid ES6 syntax');
|
|
133
|
+
} catch (error) {
|
|
112
134
|
assert(error, 'Should throw an error for invalid ES6 syntax');
|
|
113
135
|
}
|
|
114
136
|
});
|
|
@@ -116,14 +138,14 @@ describe('Error Handling Tests', function() {
|
|
|
116
138
|
|
|
117
139
|
describe('Core_JS_Single_File_Minifying_Bundler_Using_ESBuild', function() {
|
|
118
140
|
it('should handle minification errors gracefully', async function() {
|
|
119
|
-
const bundler = new Core_JS_Single_File_Minifying_Bundler_Using_ESBuild({
|
|
120
|
-
minify: { enabled: true, level: 'aggressive' }
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
try {
|
|
124
|
-
await bundler.bundle(invalidJsContent);
|
|
125
|
-
assert.fail('Should have thrown an error for invalid JavaScript during minification');
|
|
126
|
-
} catch (error) {
|
|
141
|
+
const bundler = new Core_JS_Single_File_Minifying_Bundler_Using_ESBuild({
|
|
142
|
+
minify: { enabled: true, level: 'aggressive' }
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
await await_observable(bundler.bundle(invalidJsContent));
|
|
147
|
+
assert.fail('Should have thrown an error for invalid JavaScript during minification');
|
|
148
|
+
} catch (error) {
|
|
127
149
|
assert(error, 'Should throw an error for invalid JavaScript during minification');
|
|
128
150
|
}
|
|
129
151
|
});
|
|
@@ -136,11 +158,11 @@ describe('Error Handling Tests', function() {
|
|
|
136
158
|
}
|
|
137
159
|
});
|
|
138
160
|
|
|
139
|
-
// Should not crash during construction, but may fail during bundling
|
|
140
|
-
try {
|
|
141
|
-
await bundler.bundle(validJsContent);
|
|
142
|
-
// If it succeeds, the invalid level might be ignored
|
|
143
|
-
} catch (error) {
|
|
161
|
+
// Should not crash during construction, but may fail during bundling
|
|
162
|
+
try {
|
|
163
|
+
await await_observable(bundler.bundle(validJsContent));
|
|
164
|
+
// If it succeeds, the invalid level might be ignored
|
|
165
|
+
} catch (error) {
|
|
144
166
|
// This is acceptable - invalid levels might cause errors
|
|
145
167
|
assert(error, 'Invalid minification level may cause errors');
|
|
146
168
|
}
|
|
@@ -156,12 +178,12 @@ describe('Error Handling Tests', function() {
|
|
|
156
178
|
const const = 'test';
|
|
157
179
|
return const;
|
|
158
180
|
}
|
|
159
|
-
`;
|
|
160
|
-
|
|
161
|
-
try {
|
|
162
|
-
await bundler.bundle(keywordConflictContent);
|
|
163
|
-
// ESBuild might handle this gracefully
|
|
164
|
-
} catch (error) {
|
|
181
|
+
`;
|
|
182
|
+
|
|
183
|
+
try {
|
|
184
|
+
await await_observable(bundler.bundle(keywordConflictContent));
|
|
185
|
+
// ESBuild might handle this gracefully
|
|
186
|
+
} catch (error) {
|
|
165
187
|
assert(error, 'Reserved keywords may cause minification errors');
|
|
166
188
|
}
|
|
167
189
|
});
|
|
@@ -172,15 +194,17 @@ describe('Error Handling Tests', function() {
|
|
|
172
194
|
const bundler = new Advanced_JS_Bundler_Using_ESBuild();
|
|
173
195
|
|
|
174
196
|
// Create invalid JS file
|
|
175
|
-
const invalidFile = path.join(__dirname, 'temp_invalid.js');
|
|
176
|
-
await fs.writeFile(invalidFile, invalidJsContent);
|
|
177
|
-
|
|
178
|
-
try {
|
|
179
|
-
await bundler.bundle(invalidFile);
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
assert(
|
|
183
|
-
}
|
|
197
|
+
const invalidFile = path.join(__dirname, 'temp_invalid.js');
|
|
198
|
+
await fs.writeFile(invalidFile, invalidJsContent);
|
|
199
|
+
|
|
200
|
+
try {
|
|
201
|
+
const result = await await_observable(bundler.bundle(invalidFile));
|
|
202
|
+
const js_item = result[0] && result[0]._arr && result[0]._arr.find((item) => item.type === 'JavaScript');
|
|
203
|
+
assert(js_item, 'Should return fallback JavaScript bundle item');
|
|
204
|
+
assert(js_item.text.includes('Bundling failed'), 'Fallback bundle should indicate failure');
|
|
205
|
+
} catch (error) {
|
|
206
|
+
assert(error, 'Advanced bundling should either return fallback or throw an error');
|
|
207
|
+
} finally {
|
|
184
208
|
try {
|
|
185
209
|
await fs.unlink(invalidFile);
|
|
186
210
|
} catch (err) {
|
|
@@ -205,14 +229,14 @@ describe('Error Handling Tests', function() {
|
|
|
205
229
|
|
|
206
230
|
console.log('test');
|
|
207
231
|
`;
|
|
208
|
-
|
|
209
|
-
const malformedFile = path.join(__dirname, 'temp_malformed.js');
|
|
210
|
-
await fs.writeFile(malformedFile, malformedCssContent);
|
|
211
|
-
|
|
212
|
-
try {
|
|
213
|
-
await bundler.bundle(malformedFile);
|
|
214
|
-
// Should still work even with malformed CSS in strings
|
|
215
|
-
} catch (error) {
|
|
232
|
+
|
|
233
|
+
const malformedFile = path.join(__dirname, 'temp_malformed.js');
|
|
234
|
+
await fs.writeFile(malformedFile, malformedCssContent);
|
|
235
|
+
|
|
236
|
+
try {
|
|
237
|
+
await await_observable(bundler.bundle(malformedFile));
|
|
238
|
+
// Should still work even with malformed CSS in strings
|
|
239
|
+
} catch (error) {
|
|
216
240
|
// CSS extraction errors are acceptable
|
|
217
241
|
assert(error, 'CSS extraction errors are acceptable');
|
|
218
242
|
} finally {
|
|
@@ -422,75 +446,87 @@ describe('Error Handling Tests', function() {
|
|
|
422
446
|
});
|
|
423
447
|
});
|
|
424
448
|
|
|
425
|
-
describe('Server-Level Error Handling', function() {
|
|
426
|
-
it('should handle server startup errors', async function() {
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
try {
|
|
430
|
-
await
|
|
431
|
-
ctrl: class InvalidControl {
|
|
432
|
-
// Missing required methods
|
|
433
|
-
},
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
449
|
+
describe('Server-Level Error Handling', function() {
|
|
450
|
+
it('should handle server startup errors', async function() {
|
|
451
|
+
let server_instance = null;
|
|
452
|
+
|
|
453
|
+
try {
|
|
454
|
+
server_instance = await Server.serve({
|
|
455
|
+
ctrl: class InvalidControl {
|
|
456
|
+
// Missing required methods
|
|
457
|
+
},
|
|
458
|
+
host: '127.0.0.1',
|
|
459
|
+
port: 3003,
|
|
460
|
+
bundler: {
|
|
461
|
+
compression: {
|
|
437
462
|
enabled: 'invalid'
|
|
438
463
|
}
|
|
439
464
|
}
|
|
440
|
-
});
|
|
441
|
-
assert.fail('Should have thrown an error for invalid configuration');
|
|
442
|
-
} catch (error) {
|
|
443
|
-
assert(error, 'Should throw error for invalid server configuration');
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
465
|
+
});
|
|
466
|
+
assert.fail('Should have thrown an error for invalid configuration');
|
|
467
|
+
} catch (error) {
|
|
468
|
+
assert(error, 'Should throw error for invalid server configuration');
|
|
469
|
+
} finally {
|
|
470
|
+
await close_server_instance(server_instance);
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
it('should handle port binding errors', async function() {
|
|
475
|
+
let server1 = null;
|
|
476
|
+
let server2 = null;
|
|
477
|
+
|
|
478
|
+
// Start first server
|
|
479
|
+
server1 = await Server.serve({
|
|
480
|
+
ctrl: class TestControl {
|
|
481
|
+
all_html_render() {
|
|
482
|
+
return Promise.resolve('<html></html>');
|
|
483
|
+
}
|
|
484
|
+
},
|
|
485
|
+
host: '127.0.0.1',
|
|
486
|
+
port: 3004
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
// Try to start second server on same port
|
|
490
|
+
try {
|
|
491
|
+
server2 = await Server.serve({
|
|
492
|
+
ctrl: class TestControl {
|
|
493
|
+
all_html_render() {
|
|
494
|
+
return Promise.resolve('<html></html>');
|
|
495
|
+
}
|
|
496
|
+
},
|
|
497
|
+
host: '127.0.0.1',
|
|
498
|
+
port: 3004 // Same port
|
|
499
|
+
});
|
|
500
|
+
assert.fail('Should have failed to bind to occupied port');
|
|
501
|
+
} catch (error) {
|
|
502
|
+
assert(error, 'Should throw error for port binding conflict');
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// Clean up
|
|
506
|
+
await close_server_instance(server1);
|
|
507
|
+
await close_server_instance(server2);
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
it('should handle invalid control classes', async function() {
|
|
511
|
+
let server_instance = null;
|
|
512
|
+
|
|
513
|
+
try {
|
|
514
|
+
server_instance = await Server.serve({
|
|
515
|
+
page: {
|
|
516
|
+
route: '/',
|
|
517
|
+
content: "not_a_class"
|
|
518
|
+
},
|
|
519
|
+
host: '127.0.0.1',
|
|
520
|
+
port: 3005
|
|
521
|
+
});
|
|
522
|
+
assert.fail('Should have thrown an error for invalid control');
|
|
523
|
+
} catch (error) {
|
|
524
|
+
assert(error, 'Should throw error for invalid control class');
|
|
525
|
+
} finally {
|
|
526
|
+
await close_server_instance(server_instance);
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
});
|
|
494
530
|
|
|
495
531
|
describe('Configuration Validation Errors', function() {
|
|
496
532
|
it('should validate all configuration paths', function() {
|
|
@@ -544,12 +580,12 @@ describe('Error Handling Tests', function() {
|
|
|
544
580
|
|
|
545
581
|
// Try to bundle a file in a directory without read permissions
|
|
546
582
|
// This is hard to test reliably across different systems, so we'll skip
|
|
547
|
-
// actual permission testing and just verify error handling structure
|
|
548
|
-
try {
|
|
549
|
-
await bundler.bundle('/root/private/file.js');
|
|
550
|
-
} catch (error) {
|
|
551
|
-
// Expected to fail
|
|
552
|
-
assert(error, 'Should handle permission errors');
|
|
583
|
+
// actual permission testing and just verify error handling structure
|
|
584
|
+
try {
|
|
585
|
+
await await_observable(bundler.bundle('/root/private/file.js'));
|
|
586
|
+
} catch (error) {
|
|
587
|
+
// Expected to fail
|
|
588
|
+
assert(error, 'Should handle permission errors');
|
|
553
589
|
}
|
|
554
590
|
});
|
|
555
591
|
|
|
@@ -564,11 +600,11 @@ describe('Error Handling Tests', function() {
|
|
|
564
600
|
[]
|
|
565
601
|
];
|
|
566
602
|
|
|
567
|
-
for (const invalidPath of invalidPaths) {
|
|
568
|
-
try {
|
|
569
|
-
await bundler.bundle(invalidPath);
|
|
570
|
-
// May not throw for all invalid paths
|
|
571
|
-
} catch (error) {
|
|
603
|
+
for (const invalidPath of invalidPaths) {
|
|
604
|
+
try {
|
|
605
|
+
await await_observable(bundler.bundle(invalidPath));
|
|
606
|
+
// May not throw for all invalid paths
|
|
607
|
+
} catch (error) {
|
|
572
608
|
assert(error, 'Should handle invalid file paths');
|
|
573
609
|
}
|
|
574
610
|
}
|
|
@@ -580,12 +616,12 @@ describe('Error Handling Tests', function() {
|
|
|
580
616
|
// Create a file with invalid UTF-8 content
|
|
581
617
|
const invalidUtf8File = path.join(__dirname, 'temp_invalid_utf8.js');
|
|
582
618
|
const invalidBuffer = Buffer.from([0xFF, 0xFE, 0xFD]); // Invalid UTF-8
|
|
583
|
-
await fs.writeFile(invalidUtf8File, invalidBuffer);
|
|
584
|
-
|
|
585
|
-
try {
|
|
586
|
-
await bundler.bundle(invalidUtf8File);
|
|
587
|
-
// ESBuild might handle encoding issues gracefully
|
|
588
|
-
} catch (error) {
|
|
619
|
+
await fs.writeFile(invalidUtf8File, invalidBuffer);
|
|
620
|
+
|
|
621
|
+
try {
|
|
622
|
+
await await_observable(bundler.bundle(invalidUtf8File));
|
|
623
|
+
// ESBuild might handle encoding issues gracefully
|
|
624
|
+
} catch (error) {
|
|
589
625
|
assert(error, 'Should handle encoding errors');
|
|
590
626
|
} finally {
|
|
591
627
|
try {
|
|
@@ -692,24 +728,31 @@ describe('Error Handling Tests', function() {
|
|
|
692
728
|
});
|
|
693
729
|
|
|
694
730
|
describe('Memory and Performance Error Handling', function() {
|
|
695
|
-
it('should handle out of memory conditions gracefully', async function() {
|
|
696
|
-
const bundler = new Core_JS_Single_File_Minifying_Bundler_Using_ESBuild();
|
|
697
|
-
|
|
698
|
-
// Create extremely large content that might cause OOM
|
|
699
|
-
const hugeContent = 'const data = "' + 'x'.repeat(
|
|
700
|
-
|
|
701
|
-
try {
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
731
|
+
it('should handle out of memory conditions gracefully', async function() {
|
|
732
|
+
const bundler = new Core_JS_Single_File_Minifying_Bundler_Using_ESBuild();
|
|
733
|
+
|
|
734
|
+
// Create extremely large content that might cause OOM
|
|
735
|
+
const hugeContent = 'const data = "' + 'x'.repeat(20 * 1024 * 1024) + '";'; // 20MB string
|
|
736
|
+
|
|
737
|
+
try {
|
|
738
|
+
const timeout_promise = new Promise((_, reject) => {
|
|
739
|
+
setTimeout(() => reject(new Error('oom_test_timeout')), 12000);
|
|
740
|
+
});
|
|
741
|
+
await Promise.race([
|
|
742
|
+
await_observable(bundler.bundle(hugeContent)),
|
|
743
|
+
timeout_promise
|
|
744
|
+
]);
|
|
745
|
+
// If it succeeds, that's fine
|
|
746
|
+
} catch (error) {
|
|
747
|
+
// OOM errors are acceptable for very large content
|
|
748
|
+
assert(error, 'Should handle OOM errors gracefully');
|
|
749
|
+
assert(error.message.includes('out of memory') ||
|
|
750
|
+
error.message.includes('Maximum call stack') ||
|
|
751
|
+
error.message.includes('oom_test_timeout') ||
|
|
752
|
+
error.code === 'ENOBUFS' ||
|
|
753
|
+
true, 'Error should be memory-related or acceptable');
|
|
754
|
+
}
|
|
755
|
+
});
|
|
713
756
|
|
|
714
757
|
it('should handle timeout conditions', async function() {
|
|
715
758
|
const bundler = new Core_JS_Single_File_Minifying_Bundler_Using_ESBuild();
|
|
@@ -730,10 +773,10 @@ describe('Error Handling Tests', function() {
|
|
|
730
773
|
setTimeout(() => reject(new Error('Test timeout')), 10000);
|
|
731
774
|
});
|
|
732
775
|
|
|
733
|
-
await Promise.race([
|
|
734
|
-
bundler.bundle(slowContent),
|
|
735
|
-
timeoutPromise
|
|
736
|
-
]);
|
|
776
|
+
await Promise.race([
|
|
777
|
+
await_observable(bundler.bundle(slowContent)),
|
|
778
|
+
timeoutPromise
|
|
779
|
+
]);
|
|
737
780
|
} catch (error) {
|
|
738
781
|
if (error.message === 'Test timeout') {
|
|
739
782
|
// Accept timeout - bundling can be slow
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const jsgui = require('jsgui3-html');
|
|
2
|
+
const { controls } = jsgui;
|
|
3
|
+
|
|
4
|
+
class Bundling_Default_Button_App extends controls.Active_HTML_Document {
|
|
5
|
+
constructor(spec = {}) {
|
|
6
|
+
super(spec);
|
|
7
|
+
|
|
8
|
+
if (!spec.el) {
|
|
9
|
+
this.compose_ui();
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
compose_ui() {
|
|
14
|
+
const { context } = this;
|
|
15
|
+
|
|
16
|
+
const root = new controls.div({ context });
|
|
17
|
+
root.add_class('bundle-test-root');
|
|
18
|
+
|
|
19
|
+
const label = new controls.div({ context });
|
|
20
|
+
label.add_class('bundle-test-label');
|
|
21
|
+
label.add('button-only-ui');
|
|
22
|
+
root.add(label);
|
|
23
|
+
|
|
24
|
+
const action_button = new controls.Button({
|
|
25
|
+
context,
|
|
26
|
+
text: 'Run'
|
|
27
|
+
});
|
|
28
|
+
action_button.add_class('bundle-test-button');
|
|
29
|
+
action_button.dom.attributes['data-test'] = 'bundle-test-button';
|
|
30
|
+
root.add(action_button);
|
|
31
|
+
|
|
32
|
+
this.body.add(root);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
controls.Bundling_Default_Button_App = Bundling_Default_Button_App;
|
|
37
|
+
module.exports = jsgui;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const jsgui = require('jsgui3-html');
|
|
2
|
+
const { controls } = jsgui;
|
|
3
|
+
|
|
4
|
+
class Bundling_Default_Window_App extends controls.Active_HTML_Document {
|
|
5
|
+
constructor(spec = {}) {
|
|
6
|
+
super(spec);
|
|
7
|
+
|
|
8
|
+
if (!spec.el) {
|
|
9
|
+
this.compose_ui();
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
compose_ui() {
|
|
14
|
+
const { context } = this;
|
|
15
|
+
|
|
16
|
+
const main_window = new controls.Window({
|
|
17
|
+
context,
|
|
18
|
+
title: 'Bundling Window',
|
|
19
|
+
pos: [24, 24],
|
|
20
|
+
size: [420, 260]
|
|
21
|
+
});
|
|
22
|
+
main_window.add_class('bundle-test-window');
|
|
23
|
+
|
|
24
|
+
const message = new controls.div({ context });
|
|
25
|
+
message.add_class('bundle-test-window-content');
|
|
26
|
+
message.add('window-ui-ready');
|
|
27
|
+
main_window.inner.add(message);
|
|
28
|
+
|
|
29
|
+
this.body.add(main_window);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
controls.Bundling_Default_Window_App = Bundling_Default_Window_App;
|
|
34
|
+
module.exports = jsgui;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"static_alias": {
|
|
3
|
+
"entry_file": "temp_control_scan_static_alias_client.js",
|
|
4
|
+
"uses_jsgui3_html": true,
|
|
5
|
+
"dynamic_control_access_detected": false,
|
|
6
|
+
"reachable_files": [
|
|
7
|
+
"temp_control_scan_static_alias_client.js"
|
|
8
|
+
],
|
|
9
|
+
"used_identifiers": [
|
|
10
|
+
"Active_HTML_Document",
|
|
11
|
+
"Button"
|
|
12
|
+
],
|
|
13
|
+
"selected_controls": [
|
|
14
|
+
"Active_HTML_Document",
|
|
15
|
+
"Button"
|
|
16
|
+
],
|
|
17
|
+
"unmatched_identifiers": [],
|
|
18
|
+
"package_aliases": [
|
|
19
|
+
"ui"
|
|
20
|
+
],
|
|
21
|
+
"controls_aliases": [
|
|
22
|
+
"controls",
|
|
23
|
+
"ui_controls"
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
"dynamic_alias": {
|
|
27
|
+
"entry_file": "temp_control_scan_dynamic_alias_client.js",
|
|
28
|
+
"uses_jsgui3_html": true,
|
|
29
|
+
"dynamic_control_access_detected": true,
|
|
30
|
+
"reachable_files": [
|
|
31
|
+
"temp_control_scan_dynamic_alias_client.js"
|
|
32
|
+
],
|
|
33
|
+
"used_identifiers": [
|
|
34
|
+
"Active_HTML_Document"
|
|
35
|
+
],
|
|
36
|
+
"selected_controls": [
|
|
37
|
+
"Active_HTML_Document"
|
|
38
|
+
],
|
|
39
|
+
"unmatched_identifiers": [],
|
|
40
|
+
"package_aliases": [
|
|
41
|
+
"ui"
|
|
42
|
+
],
|
|
43
|
+
"controls_aliases": [
|
|
44
|
+
"controls",
|
|
45
|
+
"ui_controls"
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
}
|