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
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Screenshot Utilities for jsgui3-server
|
|
3
|
+
*
|
|
4
|
+
* Reusable Puppeteer-based screenshot capture, extracted from
|
|
5
|
+
* tests/window-examples.puppeteer.test.js patterns.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* const { launch_browser, capture_page, close_browser } = require('./screenshot-utils');
|
|
9
|
+
* await launch_browser();
|
|
10
|
+
* const result = await capture_page('http://localhost:3600', {
|
|
11
|
+
* output_path: './screenshots/full_page.png',
|
|
12
|
+
* full_page: true
|
|
13
|
+
* });
|
|
14
|
+
* await close_browser();
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const fs = require('fs');
|
|
18
|
+
const path = require('path');
|
|
19
|
+
|
|
20
|
+
let puppeteer;
|
|
21
|
+
let browser;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Launch a headless Puppeteer browser.
|
|
25
|
+
* @param {Object} [options]
|
|
26
|
+
* @param {boolean} [options.headless=true]
|
|
27
|
+
* @param {string} [options.executable_path] - Custom Chrome/Chromium path
|
|
28
|
+
* @returns {Promise<import('puppeteer').Browser>}
|
|
29
|
+
*/
|
|
30
|
+
const launch_browser = async (options = {}) => {
|
|
31
|
+
if (browser) return browser;
|
|
32
|
+
|
|
33
|
+
if (!puppeteer) {
|
|
34
|
+
puppeteer = require('puppeteer');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const launch_options = {
|
|
38
|
+
headless: options.headless !== false ? 'new' : false,
|
|
39
|
+
args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-gpu']
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
if (options.executable_path || process.env.PUPPETEER_EXECUTABLE_PATH) {
|
|
43
|
+
launch_options.executablePath = options.executable_path || process.env.PUPPETEER_EXECUTABLE_PATH;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
browser = await puppeteer.launch(launch_options);
|
|
47
|
+
return browser;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Capture a screenshot of a URL.
|
|
52
|
+
* @param {string} url - URL to navigate to
|
|
53
|
+
* @param {Object} [options]
|
|
54
|
+
* @param {string} [options.output_path] - File path for the PNG
|
|
55
|
+
* @param {boolean} [options.full_page=true] - Capture full scrollable page
|
|
56
|
+
* @param {number} [options.width=1280] - Viewport width
|
|
57
|
+
* @param {number} [options.height=720] - Viewport height
|
|
58
|
+
* @param {number} [options.wait_ms=1000] - Wait time after load before capture
|
|
59
|
+
* @param {string} [options.wait_for_selector] - CSS selector to wait for
|
|
60
|
+
* @returns {Promise<{path: string, width: number, height: number, size_bytes: number}>}
|
|
61
|
+
*/
|
|
62
|
+
const capture_page = async (url, options = {}) => {
|
|
63
|
+
if (!browser) {
|
|
64
|
+
throw new Error('Browser not launched. Call launch_browser() first.');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const {
|
|
68
|
+
output_path,
|
|
69
|
+
full_page = true,
|
|
70
|
+
width = 1280,
|
|
71
|
+
height = 720,
|
|
72
|
+
wait_ms = 1000,
|
|
73
|
+
wait_for_selector
|
|
74
|
+
} = options;
|
|
75
|
+
|
|
76
|
+
const page = await browser.newPage();
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
await page.setViewport({ width, height });
|
|
80
|
+
await page.goto(url, { waitUntil: 'networkidle0', timeout: 30000 });
|
|
81
|
+
|
|
82
|
+
if (wait_for_selector) {
|
|
83
|
+
await page.waitForSelector(wait_for_selector, { timeout: 10000 });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (wait_ms > 0) {
|
|
87
|
+
await new Promise(r => setTimeout(r, wait_ms));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Ensure output directory exists
|
|
91
|
+
if (output_path) {
|
|
92
|
+
fs.mkdirSync(path.dirname(output_path), { recursive: true });
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const screenshot_path = output_path || path.join(process.cwd(), 'screenshot.png');
|
|
96
|
+
await page.screenshot({ path: screenshot_path, fullPage: full_page });
|
|
97
|
+
|
|
98
|
+
const stats = fs.statSync(screenshot_path);
|
|
99
|
+
const dimensions = await page.evaluate(() => ({
|
|
100
|
+
width: document.documentElement.scrollWidth,
|
|
101
|
+
height: document.documentElement.scrollHeight
|
|
102
|
+
}));
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
path: screenshot_path,
|
|
106
|
+
width: dimensions.width,
|
|
107
|
+
height: dimensions.height,
|
|
108
|
+
size_bytes: stats.size
|
|
109
|
+
};
|
|
110
|
+
} finally {
|
|
111
|
+
await page.close();
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Capture a screenshot of a specific element on a page.
|
|
117
|
+
* @param {string} url - URL to navigate to
|
|
118
|
+
* @param {string} selector - CSS selector for the element
|
|
119
|
+
* @param {Object} [options]
|
|
120
|
+
* @param {string} [options.output_path] - File path for the PNG
|
|
121
|
+
* @param {number} [options.width=1280] - Viewport width
|
|
122
|
+
* @param {number} [options.height=720] - Viewport height
|
|
123
|
+
* @param {number} [options.wait_ms=1000] - Wait time after load
|
|
124
|
+
* @returns {Promise<{path: string, width: number, height: number, size_bytes: number}>}
|
|
125
|
+
*/
|
|
126
|
+
const capture_element = async (url, selector, options = {}) => {
|
|
127
|
+
if (!browser) {
|
|
128
|
+
throw new Error('Browser not launched. Call launch_browser() first.');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const {
|
|
132
|
+
output_path,
|
|
133
|
+
width = 1280,
|
|
134
|
+
height = 720,
|
|
135
|
+
wait_ms = 1000
|
|
136
|
+
} = options;
|
|
137
|
+
|
|
138
|
+
const page = await browser.newPage();
|
|
139
|
+
|
|
140
|
+
try {
|
|
141
|
+
await page.setViewport({ width, height });
|
|
142
|
+
await page.goto(url, { waitUntil: 'networkidle0', timeout: 30000 });
|
|
143
|
+
await page.waitForSelector(selector, { timeout: 10000 });
|
|
144
|
+
|
|
145
|
+
if (wait_ms > 0) {
|
|
146
|
+
await new Promise(r => setTimeout(r, wait_ms));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (output_path) {
|
|
150
|
+
fs.mkdirSync(path.dirname(output_path), { recursive: true });
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const element = await page.$(selector);
|
|
154
|
+
if (!element) {
|
|
155
|
+
throw new Error(`Element not found: ${selector}`);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const screenshot_path = output_path || path.join(process.cwd(), 'element_screenshot.png');
|
|
159
|
+
await element.screenshot({ path: screenshot_path });
|
|
160
|
+
|
|
161
|
+
const stats = fs.statSync(screenshot_path);
|
|
162
|
+
const box = await element.boundingBox();
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
path: screenshot_path,
|
|
166
|
+
width: Math.round(box.width),
|
|
167
|
+
height: Math.round(box.height),
|
|
168
|
+
size_bytes: stats.size
|
|
169
|
+
};
|
|
170
|
+
} finally {
|
|
171
|
+
await page.close();
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Capture multiple screenshots from a single URL — full page + individual sections.
|
|
177
|
+
* @param {string} url - URL to screenshot
|
|
178
|
+
* @param {string} output_dir - Directory to save screenshots
|
|
179
|
+
* @param {Object} [options]
|
|
180
|
+
* @param {string[]} [options.section_selectors] - CSS selectors for individual section captures
|
|
181
|
+
* @param {string[]} [options.section_names] - Names for screenshot files (parallel to selectors)
|
|
182
|
+
* @param {number} [options.width=1280]
|
|
183
|
+
* @param {number} [options.height=720]
|
|
184
|
+
* @param {number} [options.wait_ms=1000]
|
|
185
|
+
* @returns {Promise<Array<{name: string, path: string, width: number, height: number, size_bytes: number}>>}
|
|
186
|
+
*/
|
|
187
|
+
const capture_url_screenshots = async (url, output_dir, options = {}) => {
|
|
188
|
+
const {
|
|
189
|
+
section_selectors = [],
|
|
190
|
+
section_names = [],
|
|
191
|
+
width = 1280,
|
|
192
|
+
height = 720,
|
|
193
|
+
wait_ms = 1000
|
|
194
|
+
} = options;
|
|
195
|
+
|
|
196
|
+
fs.mkdirSync(output_dir, { recursive: true });
|
|
197
|
+
|
|
198
|
+
const results = [];
|
|
199
|
+
|
|
200
|
+
// Full page capture
|
|
201
|
+
const full_result = await capture_page(url, {
|
|
202
|
+
output_path: path.join(output_dir, 'full_page.png'),
|
|
203
|
+
full_page: true,
|
|
204
|
+
width,
|
|
205
|
+
height,
|
|
206
|
+
wait_ms
|
|
207
|
+
});
|
|
208
|
+
results.push({ name: 'full_page', ...full_result });
|
|
209
|
+
|
|
210
|
+
// Section captures
|
|
211
|
+
for (let i = 0; i < section_selectors.length; i++) {
|
|
212
|
+
const selector = section_selectors[i];
|
|
213
|
+
const name = section_names[i] || `section_${i + 1}`;
|
|
214
|
+
|
|
215
|
+
try {
|
|
216
|
+
const section_result = await capture_element(url, selector, {
|
|
217
|
+
output_path: path.join(output_dir, `${name}.png`),
|
|
218
|
+
width,
|
|
219
|
+
height,
|
|
220
|
+
wait_ms: 500
|
|
221
|
+
});
|
|
222
|
+
results.push({ name, ...section_result });
|
|
223
|
+
} catch (err) {
|
|
224
|
+
console.warn(` ⚠ Failed to capture "${name}" (${selector}): ${err.message}`);
|
|
225
|
+
results.push({ name, error: err.message });
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return results;
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Close the Puppeteer browser.
|
|
234
|
+
*/
|
|
235
|
+
const close_browser = async () => {
|
|
236
|
+
if (browser) {
|
|
237
|
+
await browser.close();
|
|
238
|
+
browser = null;
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
module.exports = {
|
|
243
|
+
launch_browser,
|
|
244
|
+
capture_page,
|
|
245
|
+
capture_element,
|
|
246
|
+
capture_url_screenshots,
|
|
247
|
+
close_browser
|
|
248
|
+
};
|
package/module.js
CHANGED
|
@@ -16,10 +16,17 @@ jsgui.controls.Active_HTML_Document = require('./controls/Active_HTML_Document')
|
|
|
16
16
|
|
|
17
17
|
//const Resource_Publisher = require('./publishing/http-resource-publisher');
|
|
18
18
|
//jsgui.Resource_Publisher = Resource_Publisher;
|
|
19
|
-
const Server = require('./server');
|
|
20
|
-
jsgui.Server = Server;
|
|
21
|
-
jsgui.serve = Server.serve;
|
|
22
|
-
jsgui.
|
|
19
|
+
const Server = require('./server');
|
|
20
|
+
jsgui.Server = Server;
|
|
21
|
+
jsgui.serve = Server.serve;
|
|
22
|
+
jsgui.Process_Resource = Server.Process_Resource;
|
|
23
|
+
jsgui.Remote_Process_Resource = Server.Remote_Process_Resource;
|
|
24
|
+
jsgui.HTTP_SSE_Publisher = Server.HTTP_SSE_Publisher;
|
|
25
|
+
if (jsgui.Resource) {
|
|
26
|
+
jsgui.Resource.Process = Server.Process_Resource;
|
|
27
|
+
jsgui.Resource.Remote_Process = Server.Remote_Process_Resource;
|
|
28
|
+
}
|
|
29
|
+
jsgui.fs2 = require('./fs2');
|
|
23
30
|
|
|
24
31
|
// Port utilities for auto-port selection
|
|
25
32
|
const port_utils = require('./port-utils');
|
package/package.json
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"esbuild": "^0.27.1",
|
|
11
11
|
"fnl": "^0.0.37",
|
|
12
12
|
"fnlfs": "^0.0.34",
|
|
13
|
-
"jsgui3-client": "^0.0.
|
|
14
|
-
"jsgui3-html": "^0.0.
|
|
13
|
+
"jsgui3-client": "^0.0.129",
|
|
14
|
+
"jsgui3-html": "^0.0.180",
|
|
15
15
|
"jsgui3-webpage": "^0.0.8",
|
|
16
16
|
"jsgui3-website": "^0.0.8",
|
|
17
17
|
"lang-tools": "^0.0.44",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"type": "git",
|
|
44
44
|
"url": "https://github.com/metabench/jsgui3-server.git"
|
|
45
45
|
},
|
|
46
|
-
"version": "0.0.
|
|
46
|
+
"version": "0.0.149",
|
|
47
47
|
"scripts": {
|
|
48
48
|
"cli": "node cli.js",
|
|
49
49
|
"serve": "node cli.js serve",
|
|
@@ -53,13 +53,23 @@
|
|
|
53
53
|
"test:assigners": "node tests/test-runner.js --test=assigners.test.js",
|
|
54
54
|
"test:publishers": "node tests/test-runner.js --test=publishers.test.js",
|
|
55
55
|
"test:config": "node tests/test-runner.js --test=configuration-validation.test.js",
|
|
56
|
+
"test:admin-ui": "node tests/test-runner.js --test=admin-ui-render.test.js",
|
|
57
|
+
"test:serve": "node tests/test-runner.js --test=serve.test.js",
|
|
58
|
+
"test:serve:resources": "node tests/test-runner.js --test=serve-resources.test.js",
|
|
59
|
+
"test:resources:process": "node tests/test-runner.js --test=process-resource.test.js",
|
|
60
|
+
"test:resources:remote": "node tests/test-runner.js --test=remote-process-resource.test.js",
|
|
61
|
+
"test:resources:pool": "node tests/test-runner.js --test=server-resource-pool.test.js",
|
|
62
|
+
"test:sse": "node tests/test-runner.js --test=http-sse-publisher.test.js",
|
|
56
63
|
"test:e2e": "node tests/test-runner.js --test=end-to-end.test.js",
|
|
57
64
|
"test:content": "node tests/test-runner.js --test=content-analysis.test.js",
|
|
65
|
+
"test:bundler:cache": "node tests/test-runner.js --test=control-optimizer-cache-behavior.test.js",
|
|
58
66
|
"test:performance": "node tests/test-runner.js --test=performance.test.js",
|
|
59
67
|
"test:errors": "node tests/test-runner.js --test=error-handling.test.js",
|
|
60
68
|
"test:examples:controls": "node tests/test-runner.js --test=examples-controls.e2e.test.js",
|
|
69
|
+
"test:puppeteer:bundling": "node tests/test-runner.js --test=bundling-default-control-elimination.puppeteer.test.js",
|
|
61
70
|
"test:puppeteer:windows": "node tests/test-runner.js --test=window-examples.puppeteer.test.js",
|
|
71
|
+
"test:puppeteer:resources": "node tests/test-runner.js --test=window-resource-integration.puppeteer.test.js",
|
|
62
72
|
"test:debug": "node tests/test-runner.js --debug",
|
|
63
73
|
"test:verbose": "node tests/test-runner.js --verbose"
|
|
64
74
|
}
|
|
65
|
-
}
|
|
75
|
+
}
|
package/publishers/Publishers.js
CHANGED
|
@@ -7,10 +7,11 @@ const Publishers = {
|
|
|
7
7
|
'html': require('./http-html-publisher'),
|
|
8
8
|
'jpeg': require('./http-jpeg-publisher'),
|
|
9
9
|
'js': require('./http-js-publisher'),
|
|
10
|
-
'observable': require('./http-observable-publisher'),
|
|
11
|
-
'
|
|
10
|
+
'observable': require('./http-observable-publisher'),
|
|
11
|
+
'sse': require('./http-sse-publisher'),
|
|
12
|
+
'png': require('./http-png-publisher'),
|
|
12
13
|
'resource': require('./http-resource-publisher'),
|
|
13
14
|
'svg': require('./http-svg-publisher')
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
module.exports = Publishers;
|
|
17
|
+
module.exports = Publishers;
|
|
@@ -65,11 +65,11 @@ class Single_Control_Webpage_Server_Static_Compressed_Response_Buffers_Assigner
|
|
|
65
65
|
|
|
66
66
|
async assign(arr_bundled_items) {
|
|
67
67
|
// Get compression configuration with defaults
|
|
68
|
-
const enabled = this.compression_config.enabled !== false; // Default: true
|
|
69
|
-
const algorithms = this.compression_config.algorithms || ['gzip', 'br'];
|
|
70
|
-
const gzipLevel = this.compression_config.gzip?.level
|
|
71
|
-
const brotliQuality = this.compression_config.brotli?.quality
|
|
72
|
-
const threshold = this.compression_config.threshold
|
|
68
|
+
const enabled = this.compression_config.enabled !== false; // Default: true
|
|
69
|
+
const algorithms = this.compression_config.algorithms || ['gzip', 'br'];
|
|
70
|
+
const gzipLevel = this.compression_config.gzip?.level ?? 6;
|
|
71
|
+
const brotliQuality = this.compression_config.brotli?.quality ?? 6;
|
|
72
|
+
const threshold = this.compression_config.threshold ?? 1024;
|
|
73
73
|
|
|
74
74
|
if (!enabled) {
|
|
75
75
|
console.log('Compression disabled, skipping compression assignment');
|
|
@@ -27,6 +27,9 @@ class Observable_Publisher extends HTTP_Publisher {
|
|
|
27
27
|
this.type = 'observable';
|
|
28
28
|
this.obs = obs;
|
|
29
29
|
|
|
30
|
+
// Expose schema if provided (either in spec or on the observable itself)
|
|
31
|
+
this.schema = spec.schema || obs.schema || null;
|
|
32
|
+
|
|
30
33
|
this.keep_alive_interval_ms = (spec && spec.keep_alive_interval_ms !== undefined)
|
|
31
34
|
? spec.keep_alive_interval_ms
|
|
32
35
|
: default_keep_alive_interval_ms;
|
|
@@ -301,6 +304,11 @@ class Observable_Publisher extends HTTP_Publisher {
|
|
|
301
304
|
this._write_sse(res, `event: paused\ndata: ${this._stringify_sse_data({ status: 'paused' })}\n\n`);
|
|
302
305
|
}
|
|
303
306
|
|
|
307
|
+
// Send schema if available
|
|
308
|
+
if (this.schema) {
|
|
309
|
+
this._write_sse(res, `event: schema\ndata: ${this._stringify_sse_data(this.schema)}\n\n`);
|
|
310
|
+
}
|
|
311
|
+
|
|
304
312
|
let removed = false;
|
|
305
313
|
const remove_connection = () => {
|
|
306
314
|
if (removed) return;
|