jsgui3-server 0.0.147 → 0.0.149

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/.github/workflows/control-scan-manifest-check.yml +31 -0
  2. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-071799b982906680f5fd699d.js +40 -0
  3. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-07352945ad5c92654fcb8b65.js +39 -0
  4. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-138a601fadb6191ea314c6fd.js +39 -0
  5. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-171f6c381c2cadf2e9fa7087.js +39 -0
  6. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-1d973388156b84a04373fac9.js +39 -0
  7. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-20e117bc8a10d2cd16234bbe.js +40 -0
  8. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-2b028a82b0e5efddba42425f.js +39 -0
  9. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-4518556cd5c7e059e82b22b8.js +40 -0
  10. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-5bac1aa0f213902f718ed74f.js +40 -0
  11. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-5f9996ac7822caf777d92f56.js +39 -0
  12. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-60a92c702e65fd9cf748e3ec.js +39 -0
  13. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-6164c1f8f738995c541895d2.js +44 -0
  14. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-6718a85eb9e5aa782dd47a05.js +45 -0
  15. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-69e280f14e37aee76a1d4675.js +39 -0
  16. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7570d1b030d44b111ed59c4c.js +39 -0
  17. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7798c9bbd55e510d5039f936.js +42 -0
  18. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-78cd511ea1ef18ecb03d1be5.js +40 -0
  19. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7d482e0b95bcb5e3c543118b.js +43 -0
  20. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-80e9476d1127c55b40fdb36f.js +40 -0
  21. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-810ced55d5320a3088a05b13.js +40 -0
  22. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-8423565f1a40e329afc8c6cf.js +40 -0
  23. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-900bef783b8cee36506ec282.js +39 -0
  24. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-a1a37aff6416fdad74040ddf.js +39 -0
  25. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-ad48d5e8eda40f175b4df090.js +39 -0
  26. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-aec5a2d963015528c9099462.js +39 -0
  27. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-af9d34e0f1722fab9e28c269.js +39 -0
  28. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-b818e4015e2f1fe86280b5ab.js +41 -0
  29. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-bcb2541adc70b7aba61768c5.js +44 -0
  30. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-bfe89d2c78ed44f95ed7dd73.js +40 -0
  31. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-c06f04806a1e688e1187110c.js +40 -0
  32. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-c3f3adf904f585afc544b96a.js +39 -0
  33. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-d45acb873e1d8e32d5e60f2e.js +39 -0
  34. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-db06f132533706f4a0163b8c.js +39 -0
  35. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-f660f40d78b135fc8560a862.js +39 -0
  36. package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-f9dee4ec18a96e09bee06bae.js +39 -0
  37. package/README.md +85 -3
  38. package/admin-ui/client.js +213 -0
  39. package/admin-ui/server.js +104 -0
  40. package/client/controls/auto-observable.js +207 -0
  41. package/dev-status.svg +139 -0
  42. package/docs/api-reference.md +301 -43
  43. package/docs/books/admin-ui/01-introduction.md +32 -0
  44. package/docs/books/admin-ui/02-architecture.md +92 -0
  45. package/docs/books/admin-ui/03-controls.md +194 -0
  46. package/docs/books/admin-ui/04-implementation-plan.md +62 -0
  47. package/docs/books/admin-ui/README.md +26 -0
  48. package/docs/books/jsgui3-bundling-research-book/00-table-of-contents.md +35 -0
  49. package/docs/books/jsgui3-bundling-research-book/01-pipeline-and-runtime-semantics.md +34 -0
  50. package/docs/books/jsgui3-bundling-research-book/02-javascript-bundling-core.md +36 -0
  51. package/docs/books/jsgui3-bundling-research-book/03-style-extraction-and-css-compilation.md +35 -0
  52. package/docs/books/jsgui3-bundling-research-book/04-static-publishing-and-delivery.md +39 -0
  53. package/docs/books/jsgui3-bundling-research-book/05-current-limits-and-size-bloat-vectors.md +25 -0
  54. package/docs/books/jsgui3-bundling-research-book/06-unused-module-elimination-strategy.md +77 -0
  55. package/docs/books/jsgui3-bundling-research-book/07-jsgui3-html-control-and-mixin-pruning.md +63 -0
  56. package/docs/books/jsgui3-bundling-research-book/08-test-and-verification-methodology.md +43 -0
  57. package/docs/books/jsgui3-bundling-research-book/09-roadmap-and-rollout.md +42 -0
  58. package/docs/books/jsgui3-bundling-research-book/10-further-research-strategies-and-upgrades.md +211 -0
  59. package/docs/books/jsgui3-bundling-research-book/README.md +35 -0
  60. package/docs/bundling-system-deep-dive.md +9 -4
  61. package/docs/comprehensive-documentation.md +49 -18
  62. package/docs/configuration-reference.md +152 -27
  63. package/docs/core/README.md +19 -0
  64. package/docs/core/jsgui3-server-core-book/00-table-of-contents.md +21 -0
  65. package/docs/core/jsgui3-server-core-book/01-startup-readiness-state-machine.md +41 -0
  66. package/docs/core/jsgui3-server-core-book/02-resource-abstraction-and-lifecycle.md +92 -0
  67. package/docs/core/jsgui3-server-core-book/03-resource-pool-and-event-topology.md +47 -0
  68. package/docs/core/jsgui3-server-core-book/04-sse-publisher-semantics.md +41 -0
  69. package/docs/core/jsgui3-server-core-book/05-serve-factory-resource-wiring.md +46 -0
  70. package/docs/core/jsgui3-server-core-book/06-e2e-testing-methodology.md +48 -0
  71. package/docs/core/jsgui3-server-core-book/07-defect-detection-and-hardening-loop.md +47 -0
  72. package/docs/publishers-guide.md +59 -4
  73. package/docs/resources-guide.md +184 -35
  74. package/docs/simple-server-api-design.md +72 -17
  75. package/docs/system-architecture.md +18 -14
  76. package/examples/controls/15) window, observable SSE/server.js +6 -1
  77. package/examples/controls/19) window, auto observable ui/client.js +125 -0
  78. package/examples/controls/19) window, auto observable ui/server.js +73 -0
  79. package/examples/controls/20) window, task manager app/README.md +133 -0
  80. package/examples/controls/20) window, task manager app/client.js +797 -0
  81. package/examples/controls/20) window, task manager app/server.js +178 -0
  82. package/examples/controls/6) window, color_palette/client.js +165 -68
  83. package/examples/controls/9) window, date picker/client.js +362 -76
  84. package/examples/controls/9b) window, shared data.model mirrored date pickers/client.js +104 -83
  85. package/examples/jsgui3-html/06) theming/client.js +22 -1
  86. package/examples/jsgui3-html/10) binding-debugger/client.js +137 -1
  87. package/http/responders/static/Static_Route_HTTP_Responder.js +52 -34
  88. package/lab/experiments/capture-color-controls.js +196 -0
  89. package/lab/results/screenshots/color-controls/full_page.png +0 -0
  90. package/lab/results/screenshots/color-controls/section_1_color_grid_12x12.png +0 -0
  91. package/lab/results/screenshots/color-controls/section_2_color_grid_4x2.png +0 -0
  92. package/lab/results/screenshots/color-controls/section_3_color_palette.png +0 -0
  93. package/lab/results/screenshots/color-controls/section_4_palette_comparison.png +0 -0
  94. package/lab/results/screenshots/color-controls/section_5_raw_swatches.png +0 -0
  95. package/lab/results/screenshots/color-controls/section_6_optimized_crayola.png +0 -0
  96. package/lab/results/screenshots/color-controls/section_7_pastel_palette.png +0 -0
  97. package/lab/results/screenshots/color-controls/section_8_extended_144.png +0 -0
  98. package/lab/screenshot-utils.js +248 -0
  99. package/module.js +11 -4
  100. package/package.json +14 -4
  101. package/publishers/Publishers.js +4 -3
  102. package/publishers/helpers/assigners/static-compressed-response-buffers/Single_Control_Webpage_Server_Static_Compressed_Response_Buffers_Assigner.js +5 -5
  103. package/publishers/http-observable-publisher.js +8 -0
  104. package/publishers/http-sse-publisher.js +341 -0
  105. package/publishers/http-webpage-publisher.js +13 -3
  106. package/publishers/http-webpageorsite-publisher.js +18 -0
  107. package/resources/process-resource.js +950 -0
  108. package/resources/processors/bundlers/js/esbuild/Advanced_JS_Bundler_Using_ESBuild.js +164 -46
  109. package/resources/processors/bundlers/js/esbuild/Core_JS_Non_Minifying_Bundler_Using_ESBuild.js +18 -7
  110. package/resources/processors/bundlers/js/esbuild/JSGUI3_HTML_Control_Optimizer.js +829 -0
  111. package/resources/remote-process-resource.js +355 -0
  112. package/resources/server-resource-pool.js +354 -41
  113. package/serve-factory.js +441 -259
  114. package/server.js +161 -16
  115. package/tests/README.md +66 -4
  116. package/tests/admin-ui-render.test.js +24 -0
  117. package/tests/assigners.test.js +56 -40
  118. package/tests/bundling-default-control-elimination.puppeteer.test.js +260 -0
  119. package/tests/configuration-validation.test.js +21 -18
  120. package/tests/content-analysis.test.js +7 -6
  121. package/tests/control-optimizer-cache-behavior.test.js +52 -0
  122. package/tests/control-scan-manifest-regression.test.js +144 -0
  123. package/tests/end-to-end.test.js +15 -14
  124. package/tests/error-handling.test.js +222 -179
  125. package/tests/fixtures/bundling-default-button-client.js +37 -0
  126. package/tests/fixtures/bundling-default-window-client.js +34 -0
  127. package/tests/fixtures/control_scan_manifest_expectations.json +48 -0
  128. package/tests/fixtures/resource-monitor-client.js +319 -0
  129. package/tests/helpers/puppeteer-e2e-harness.js +317 -0
  130. package/tests/http-sse-publisher.test.js +136 -0
  131. package/tests/performance.test.js +69 -65
  132. package/tests/process-resource.test.js +138 -0
  133. package/tests/publishers.test.js +7 -7
  134. package/tests/remote-process-resource.test.js +160 -0
  135. package/tests/sass-controls.e2e.test.js +7 -1
  136. package/tests/serve-resources.test.js +270 -0
  137. package/tests/serve.test.js +120 -50
  138. package/tests/server-resource-pool.test.js +106 -0
  139. package/tests/small-controls-bundle-size.test.js +252 -0
  140. package/tests/test-runner.js +13 -1
  141. package/tests/window-examples.puppeteer.test.js +204 -1
  142. package/tests/window-resource-integration.puppeteer.test.js +585 -0
  143. package/tests/temp_invalid.js +0 -7
  144. package/tests/temp_invalid_utf8.js +0 -1
  145. package/tests/temp_malformed.js +0 -10
@@ -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
- describe('Error Handling Tests', function() {
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
- assert.fail('Should have thrown an error for invalid JavaScript in advanced bundling');
181
- } catch (error) {
182
- assert(error, 'Should throw an error for invalid JavaScript in advanced bundling');
183
- } finally {
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
- const server = new Server();
428
-
429
- try {
430
- await server.serve({
431
- ctrl: class InvalidControl {
432
- // Missing required methods
433
- },
434
- port: 3003,
435
- bundler: {
436
- compression: {
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
- it('should handle port binding errors', async function() {
448
- const server1 = new Server();
449
- const server2 = new Server();
450
-
451
- // Start first server
452
- await server1.serve({
453
- ctrl: class TestControl {
454
- all_html_render() {
455
- return Promise.resolve('<html></html>');
456
- }
457
- },
458
- port: 3004
459
- });
460
-
461
- // Try to start second server on same port
462
- try {
463
- await server2.serve({
464
- ctrl: class TestControl {
465
- all_html_render() {
466
- return Promise.resolve('<html></html>');
467
- }
468
- },
469
- port: 3004 // Same port
470
- });
471
- assert.fail('Should have failed to bind to occupied port');
472
- } catch (error) {
473
- assert(error, 'Should throw error for port binding conflict');
474
- }
475
-
476
- // Clean up
477
- await server1.stop();
478
- });
479
-
480
- it('should handle invalid control classes', async function() {
481
- const server = new Server();
482
-
483
- try {
484
- await server.serve({
485
- ctrl: "not_a_class", // Invalid control
486
- port: 3005
487
- });
488
- assert.fail('Should have thrown an error for invalid control');
489
- } catch (error) {
490
- assert(error, 'Should throw error for invalid control class');
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(100 * 1024 * 1024) + '";'; // 100MB string
700
-
701
- try {
702
- await bundler.bundle(hugeContent);
703
- // If it succeeds, that's fine
704
- } catch (error) {
705
- // OOM errors are acceptable for very large content
706
- assert(error, 'Should handle OOM errors gracefully');
707
- assert(error.message.includes('out of memory') ||
708
- error.message.includes('Maximum call stack') ||
709
- error.code === 'ENOBUFS' ||
710
- true, 'Error should be memory-related or acceptable');
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
+ }