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
@@ -0,0 +1,355 @@
1
+ const { Resource } = require('jsgui3-html');
2
+ const http = require('http');
3
+ const https = require('https');
4
+
5
+ const default_poll_interval_ms = 30000;
6
+ const default_http_timeout_ms = 6000;
7
+ const default_history_size = 100;
8
+ const default_unreachable_failures_before_event = 3;
9
+
10
+ const to_error_message = (error_value) => {
11
+ if (!error_value) return null;
12
+ if (typeof error_value === 'string') return error_value;
13
+ if (error_value instanceof Error) return error_value.message;
14
+ return String(error_value);
15
+ };
16
+
17
+ class Remote_Process_Resource extends Resource {
18
+ constructor(spec = {}) {
19
+ super(spec);
20
+
21
+ this.host = spec.host || '127.0.0.1';
22
+ this.port = Number(spec.port) || 80;
23
+ this.protocol = String(spec.protocol || 'http').toLowerCase();
24
+ this.poll_interval_ms = Number.isFinite(spec.pollIntervalMs)
25
+ ? Number(spec.pollIntervalMs)
26
+ : default_poll_interval_ms;
27
+ this.http_timeout_ms = Number.isFinite(spec.httpTimeoutMs)
28
+ ? Number(spec.httpTimeoutMs)
29
+ : default_http_timeout_ms;
30
+
31
+ this.endpoints = {
32
+ status: '/',
33
+ start: '/api/start',
34
+ stop: '/api/stop',
35
+ health: '/api/health',
36
+ ...(spec.endpoints || {})
37
+ };
38
+
39
+ this.history_size = Number.isInteger(spec.historySize)
40
+ ? spec.historySize
41
+ : default_history_size;
42
+ this.unreachable_failures_before_event = Number.isInteger(spec.unreachableFailuresBeforeEvent)
43
+ ? spec.unreachableFailuresBeforeEvent
44
+ : default_unreachable_failures_before_event;
45
+
46
+ this.state = 'stopped';
47
+ this.last_polled_status = null;
48
+ this.last_polled_at = null;
49
+ this.consecutive_failures = 0;
50
+ this.history = [];
51
+
52
+ this._poll_timer = null;
53
+ this._unreachable_raised = false;
54
+ this._operation_promise = Promise.resolve();
55
+ }
56
+
57
+ _set_state(next_state) {
58
+ const previous_state = this.state;
59
+ if (previous_state === next_state) {
60
+ return;
61
+ }
62
+ this.state = next_state;
63
+ this.raise('state_change', {
64
+ from: previous_state,
65
+ to: next_state,
66
+ timestamp: Date.now()
67
+ });
68
+ }
69
+
70
+ _enqueue_operation(operation_fn) {
71
+ const next_promise = this._operation_promise.then(() => operation_fn());
72
+ this._operation_promise = next_promise.catch(() => {
73
+ // Keep the operation chain alive.
74
+ });
75
+ return next_promise;
76
+ }
77
+
78
+ _resolve_with_optional_callback(operation_promise, callback) {
79
+ if (typeof callback === 'function') {
80
+ operation_promise.then(
81
+ (result) => callback(null, result),
82
+ (error) => callback(error)
83
+ );
84
+ return;
85
+ }
86
+ return operation_promise;
87
+ }
88
+
89
+ _normalize_path(endpoint_path) {
90
+ if (!endpoint_path) return '/';
91
+ if (endpoint_path.startsWith('/')) return endpoint_path;
92
+ return `/${endpoint_path}`;
93
+ }
94
+
95
+ _request_json(method, endpoint_path, body) {
96
+ return new Promise((resolve, reject) => {
97
+ const request_module = this.protocol === 'https' ? https : http;
98
+ const normalized_path = this._normalize_path(endpoint_path);
99
+
100
+ const request_options = {
101
+ method,
102
+ host: this.host,
103
+ port: this.port,
104
+ path: normalized_path,
105
+ timeout: this.http_timeout_ms,
106
+ headers: {
107
+ 'Accept': 'application/json'
108
+ }
109
+ };
110
+
111
+ let request_payload = null;
112
+ if (body !== undefined) {
113
+ request_payload = Buffer.from(JSON.stringify(body), 'utf8');
114
+ request_options.headers['Content-Type'] = 'application/json';
115
+ request_options.headers['Content-Length'] = request_payload.length;
116
+ }
117
+
118
+ const request = request_module.request(request_options, (response) => {
119
+ const response_chunks = [];
120
+ response.on('data', (chunk) => response_chunks.push(chunk));
121
+ response.on('end', () => {
122
+ const raw_body = Buffer.concat(response_chunks).toString('utf8');
123
+ let parsed_body = null;
124
+ if (raw_body.length > 0) {
125
+ try {
126
+ parsed_body = JSON.parse(raw_body);
127
+ } catch {
128
+ parsed_body = raw_body;
129
+ }
130
+ }
131
+
132
+ const response_result = {
133
+ statusCode: response.statusCode,
134
+ headers: response.headers,
135
+ body: parsed_body,
136
+ rawBody: raw_body
137
+ };
138
+
139
+ if (response.statusCode >= 400) {
140
+ const error = new Error(`Remote process request failed with status ${response.statusCode}`);
141
+ error.response = response_result;
142
+ reject(error);
143
+ return;
144
+ }
145
+
146
+ resolve(response_result);
147
+ });
148
+ });
149
+
150
+ request.once('timeout', () => {
151
+ request.destroy(new Error(`Request timed out after ${this.http_timeout_ms}ms`));
152
+ });
153
+ request.once('error', reject);
154
+
155
+ if (request_payload) {
156
+ request.write(request_payload);
157
+ }
158
+ request.end();
159
+ });
160
+ }
161
+
162
+ _extract_state_from_payload(status_payload) {
163
+ if (!status_payload || typeof status_payload !== 'object') {
164
+ return null;
165
+ }
166
+
167
+ if (typeof status_payload.state === 'string') {
168
+ return status_payload.state;
169
+ }
170
+
171
+ if (typeof status_payload.status === 'string') {
172
+ return status_payload.status;
173
+ }
174
+
175
+ if (typeof status_payload.running === 'boolean') {
176
+ return status_payload.running ? 'running' : 'stopped';
177
+ }
178
+
179
+ return null;
180
+ }
181
+
182
+ _record_snapshot(snapshot) {
183
+ this.history.push(snapshot);
184
+ while (this.history.length > this.history_size) {
185
+ this.history.shift();
186
+ }
187
+ }
188
+
189
+ _start_polling() {
190
+ if (this._poll_timer) {
191
+ return;
192
+ }
193
+
194
+ this._poll_timer = setInterval(() => {
195
+ this._poll_status_once().catch(() => {
196
+ // Poll failures are handled within _poll_status_once.
197
+ });
198
+ }, this.poll_interval_ms);
199
+ this._poll_timer.unref?.();
200
+ }
201
+
202
+ _stop_polling() {
203
+ if (this._poll_timer) {
204
+ clearInterval(this._poll_timer);
205
+ this._poll_timer = null;
206
+ }
207
+ }
208
+
209
+ async _poll_status_once() {
210
+ try {
211
+ const response = await this._request_json('GET', this.endpoints.status);
212
+ const status_payload = response.body && typeof response.body === 'object'
213
+ ? response.body
214
+ : { raw: response.body };
215
+
216
+ const inferred_state = this._extract_state_from_payload(status_payload) || this.state;
217
+ const now_timestamp = Date.now();
218
+
219
+ this.last_polled_status = status_payload;
220
+ this.last_polled_at = now_timestamp;
221
+ this.consecutive_failures = 0;
222
+
223
+ this._record_snapshot({
224
+ timestamp: now_timestamp,
225
+ status: status_payload,
226
+ state: inferred_state,
227
+ reachable: true
228
+ });
229
+
230
+ if (this.state === 'unreachable') {
231
+ this.raise('recovered', {
232
+ timestamp: now_timestamp,
233
+ status: status_payload
234
+ });
235
+ }
236
+ this._unreachable_raised = false;
237
+ this._set_state(inferred_state);
238
+
239
+ return this.status;
240
+ } catch (error) {
241
+ const now_timestamp = Date.now();
242
+ this.consecutive_failures += 1;
243
+ this.last_polled_at = now_timestamp;
244
+
245
+ this._record_snapshot({
246
+ timestamp: now_timestamp,
247
+ reachable: false,
248
+ error: to_error_message(error)
249
+ });
250
+
251
+ if (this.state !== 'unreachable') {
252
+ this._set_state('unreachable');
253
+ }
254
+
255
+ if (!this._unreachable_raised && this.consecutive_failures >= this.unreachable_failures_before_event) {
256
+ this._unreachable_raised = true;
257
+ this.raise('unreachable', {
258
+ timestamp: now_timestamp,
259
+ consecutiveFailures: this.consecutive_failures,
260
+ error: to_error_message(error)
261
+ });
262
+ }
263
+
264
+ throw error;
265
+ }
266
+ }
267
+
268
+ async _post_control(endpoint_key, payload) {
269
+ const endpoint_path = this.endpoints[endpoint_key];
270
+ if (!endpoint_path) {
271
+ throw new Error(`Missing endpoint configuration for ${endpoint_key}`);
272
+ }
273
+
274
+ const response = await this._request_json('POST', endpoint_path, payload);
275
+ return response.body;
276
+ }
277
+
278
+ start(callback) {
279
+ const operation_promise = this._enqueue_operation(async () => {
280
+ await this._post_control('start');
281
+ this._start_polling();
282
+ await this._poll_status_once();
283
+ return this.status;
284
+ });
285
+ return this._resolve_with_optional_callback(operation_promise, callback);
286
+ }
287
+
288
+ stop(callback) {
289
+ const operation_promise = this._enqueue_operation(async () => {
290
+ try {
291
+ await this._post_control('stop');
292
+ } finally {
293
+ this._stop_polling();
294
+ }
295
+
296
+ this._set_state('stopped');
297
+ return this.status;
298
+ });
299
+ return this._resolve_with_optional_callback(operation_promise, callback);
300
+ }
301
+
302
+ restart(callback) {
303
+ const operation_promise = this._enqueue_operation(async () => {
304
+ await this._post_control('stop');
305
+ await this._post_control('start');
306
+ this._start_polling();
307
+ await this._poll_status_once();
308
+ return this.status;
309
+ });
310
+ return this._resolve_with_optional_callback(operation_promise, callback);
311
+ }
312
+
313
+ get status() {
314
+ const remote_status = this.last_polled_status && typeof this.last_polled_status === 'object'
315
+ ? this.last_polled_status
316
+ : {};
317
+ const uptime_value = Number(remote_status.uptime || remote_status.uptimeMs || 0) || 0;
318
+ const restart_count_value = Number(remote_status.restartCount || remote_status.restart_count || 0) || 0;
319
+ const memory_usage_value = remote_status.memoryUsage || remote_status.memory_usage || null;
320
+ const last_health_check_value = remote_status.lastHealthCheck || remote_status.last_health_check || null;
321
+ const pid_value = Number.isFinite(remote_status.pid) ? remote_status.pid : null;
322
+
323
+ return {
324
+ state: this.state,
325
+ pid: pid_value,
326
+ uptime: uptime_value,
327
+ restartCount: restart_count_value,
328
+ lastHealthCheck: last_health_check_value,
329
+ memoryUsage: memory_usage_value,
330
+ processManager: {
331
+ type: 'remote'
332
+ },
333
+ host: this.host,
334
+ port: this.port,
335
+ lastPolledAt: this.last_polled_at,
336
+ pollIntervalMs: this.poll_interval_ms,
337
+ httpTimeoutMs: this.http_timeout_ms,
338
+ consecutiveFailures: this.consecutive_failures,
339
+ remote: this.last_polled_status
340
+ };
341
+ }
342
+
343
+ get_abstract() {
344
+ return {
345
+ name: this.name,
346
+ state: this.state,
347
+ host: this.host,
348
+ port: this.port,
349
+ consecutiveFailures: this.consecutive_failures,
350
+ lastPolledAt: this.last_polled_at
351
+ };
352
+ }
353
+ }
354
+
355
+ module.exports = Remote_Process_Resource;