jsgui3-server 0.0.146 → 0.0.147

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.
@@ -1,9 +1,9 @@
1
1
 
2
2
 
3
3
 
4
- const {each, Router, tof} = require('jsgui3-html');
4
+ const { each, Router, tof } = require('jsgui3-html');
5
5
  const HTTP_Publisher = require('./http-publisher');
6
- const {obs} = require('fnl');
6
+ const { obs } = require('fnl');
7
7
 
8
8
  // The Webpage bundler should be able to come up with the compiled JS and CSS, maybe even a favicon.
9
9
 
@@ -97,9 +97,9 @@ class HTTP_Webpageorsite_Publisher extends HTTP_Publisher {
97
97
  constructor(spec) {
98
98
  super(spec);
99
99
 
100
- if (spec.debug !== undefined) this.debug = spec.debug;
101
- this.style_config = spec.style || {};
102
- this.bundler_config = spec.bundler || {};
100
+ if (spec.debug !== undefined) this.debug = spec.debug;
101
+ this.style_config = spec.style || {};
102
+ this.bundler_config = spec.bundler || {};
103
103
 
104
104
  // But then some properties to do with the js client(s?) file path.
105
105
 
@@ -109,37 +109,37 @@ class HTTP_Webpageorsite_Publisher extends HTTP_Publisher {
109
109
  // js_client_file_path ??? client_js_file_path???
110
110
 
111
111
  let src_path_client_js;
112
- if (spec.disk_path_client_js) {
113
- src_path_client_js = spec.disk_path_client_js;
114
- } else if (spec.src_path_client_js) {
115
- src_path_client_js = spec.src_path_client_js;
116
- } else if (spec.source_path_client_js) {
117
- src_path_client_js = spec.source_path_client_js;
118
- };
112
+ if (spec.disk_path_client_js) {
113
+ src_path_client_js = spec.disk_path_client_js;
114
+ } else if (spec.src_path_client_js) {
115
+ src_path_client_js = spec.src_path_client_js;
116
+ } else if (spec.source_path_client_js) {
117
+ src_path_client_js = spec.source_path_client_js;
118
+ };
119
119
 
120
- // or src_path_client_js as well...
120
+ // or src_path_client_js as well...
121
121
 
122
- Object.defineProperty(this, 'disk_path_client_js', {get: () => src_path_client_js, set: (value) => src_path_client_js = value});
123
- Object.defineProperty(this, 'src_path_client_js', {get: () => src_path_client_js, set: (value) => src_path_client_js = value});
124
- Object.defineProperty(this, 'source_path_client_js', {get: () => src_path_client_js, set: (value) => src_path_client_js = value});
122
+ Object.defineProperty(this, 'disk_path_client_js', { get: () => src_path_client_js, set: (value) => src_path_client_js = value });
123
+ Object.defineProperty(this, 'src_path_client_js', { get: () => src_path_client_js, set: (value) => src_path_client_js = value });
124
+ Object.defineProperty(this, 'source_path_client_js', { get: () => src_path_client_js, set: (value) => src_path_client_js = value });
125
125
 
126
126
 
127
127
  // But then need to have some things that get it ready on this level...
128
128
 
129
129
  // Maybe need a get_ready (async or obs) function....
130
130
 
131
- this.js_bundler = new JS_Bundler({
132
- 'debug': this.debug || false,
133
- 'style': this.style_config,
134
- 'bundler': this.bundler_config
135
- });
131
+ this.js_bundler = new JS_Bundler({
132
+ 'debug': this.debug || false,
133
+ 'style': this.style_config,
134
+ 'bundler': this.bundler_config
135
+ });
136
136
 
137
137
 
138
138
  }
139
139
 
140
140
  async get_ready() {
141
141
 
142
- const {js_bundler} = this;
142
+ const { js_bundler } = this;
143
143
  //await super.get_ready(); // Does not have one
144
144
 
145
145
  // Then bundle (extract (process) everything in and referenced by the JS file (s) into a bundle object)
@@ -158,20 +158,33 @@ class HTTP_Webpageorsite_Publisher extends HTTP_Publisher {
158
158
  // Single js client for whole website??? Could work, not so sure.
159
159
  // Appropriate defalt setting (using v explicit classes) will help it to work.
160
160
 
161
-
162
-
163
- const {src_path_client_js} = this;
164
-
165
- //console.log('src_path_client_js', src_path_client_js);
166
-
161
+ const { src_path_client_js } = this;
162
+
163
+ console.log('[HTTP_Webpageorsite_Publisher] get_ready called, src_path_client_js:', src_path_client_js);
164
+
165
+ // Skip bundling if no client.js path is provided
166
+ // This allows Server.serve() to work with SSR-only controls
167
+ if (!src_path_client_js) {
168
+ console.log('[HTTP_Webpageorsite_Publisher] No src_path_client_js provided - skipping JS bundling');
169
+ // Return an empty bundle with minimal CSS and JS
170
+ const empty_bundle = new Bundle();
171
+ empty_bundle.push({
172
+ type: 'CSS',
173
+ extension: 'css',
174
+ text: '/* No client CSS */'
175
+ });
176
+ empty_bundle.push({
177
+ type: 'JavaScript',
178
+ extension: 'js',
179
+ text: '/* No client JS - SSR only */'
180
+ });
181
+ return empty_bundle;
182
+ }
167
183
 
168
184
  // The js_bundler may need to operate in 'debug' mode.
169
-
170
185
  const js_bundler_res = await js_bundler.bundle(src_path_client_js);
171
186
  // Should also get the CSS from it....
172
187
 
173
-
174
-
175
188
  //console.log('js_bundler_res', js_bundler_res);
176
189
 
177
190
  // Res of length 2 - with a css item and a js item.
@@ -182,7 +195,7 @@ class HTTP_Webpageorsite_Publisher extends HTTP_Publisher {
182
195
 
183
196
  const css_item = bundle._arr.find((item) => item.type === 'CSS');
184
197
  const js_item = bundle._arr.find((item) => item.type === 'JavaScript');
185
-
198
+
186
199
  if (css_item && js_item) {
187
200
 
188
201
  return bundle;
@@ -261,7 +274,7 @@ class HTTP_Webpageorsite_Publisher extends HTTP_Publisher {
261
274
  // This part here is just getting ready to publish.
262
275
 
263
276
 
264
-
277
+
265
278
 
266
279
 
267
280
 
@@ -312,7 +325,7 @@ class HTTP_Webpageorsite_Publisher extends HTTP_Publisher {
312
325
  console.trace();
313
326
  throw 'stop';
314
327
 
315
-
328
+
316
329
 
317
330
  } else {
318
331
  console.log('js_bundler_res', js_bundler_res);
@@ -330,7 +343,7 @@ class HTTP_Webpageorsite_Publisher extends HTTP_Publisher {
330
343
 
331
344
 
332
345
 
333
-
346
+
334
347
 
335
348
 
336
349
 
package/server.js CHANGED
@@ -1,8 +1,8 @@
1
1
  const jsgui = require('jsgui3-html'),
2
2
  http = require('http'),
3
3
  https = require('https'),
4
- {prop, read_only} = require('obext'),
5
- fs = require('fs'),
4
+ { prop, read_only } = require('obext'),
5
+ fs = require('fs'),
6
6
  Resource = jsgui.Resource,
7
7
  Server_Resource_Pool = require('./resources/server-resource-pool'),
8
8
  Router = jsgui.Router,
@@ -15,7 +15,7 @@ const jsgui = require('jsgui3-html'),
15
15
  tof
16
16
  } = jsgui;
17
17
 
18
-
18
+
19
19
  const lib_path = require('path');
20
20
  const Web_Admin_Page_Control = require('./controls/page/admin');
21
21
  const Web_Admin_Panel_Control = require('./controls/panel/admin');
@@ -24,6 +24,7 @@ const HTTP_Website_Publisher = require('./publishers/http-website-publisher');
24
24
  const Webpage = require('./website/webpage');
25
25
  const HTTP_Webpage_Publisher = require('./publishers/http-webpage-publisher');
26
26
  const HTTP_Function_Publisher = require('./publishers/http-function-publisher');
27
+ const HTTP_Observable_Publisher = require('./publishers/http-observable-publisher');
27
28
 
28
29
  const Static_Route_HTTP_Responder = require('./http/responders/static/Static_Route_HTTP_Responder');
29
30
 
@@ -45,23 +46,23 @@ class JSGUI_Single_Process_Server extends Evented_Class {
45
46
  };
46
47
 
47
48
 
48
- if (spec.debug !== undefined) {
49
- this.debug = spec.debug;
50
- }
51
-
52
- const style_config = spec.style;
53
- const bundler_config = spec.bundler;
49
+ if (spec.debug !== undefined) {
50
+ this.debug = spec.debug;
51
+ }
52
+
53
+ const style_config = spec.style;
54
+ const bundler_config = spec.bundler;
54
55
 
55
56
  // or src_path_client_js as well...
56
57
 
57
- Object.defineProperty(this, 'disk_path_client_js', {get: () => disk_path_client_js, set: (value) => disk_path_client_js = value});
58
- Object.defineProperty(this, 'src_path_client_js', {get: () => disk_path_client_js, set: (value) => disk_path_client_js = value});
59
- Object.defineProperty(this, 'source_path_client_js', {get: () => disk_path_client_js, set: (value) => disk_path_client_js = value});
58
+ Object.defineProperty(this, 'disk_path_client_js', { get: () => disk_path_client_js, set: (value) => disk_path_client_js = value });
59
+ Object.defineProperty(this, 'src_path_client_js', { get: () => disk_path_client_js, set: (value) => disk_path_client_js = value });
60
+ Object.defineProperty(this, 'source_path_client_js', { get: () => disk_path_client_js, set: (value) => disk_path_client_js = value });
60
61
 
61
62
  let Ctrl = spec.Ctrl || undefined
62
- Object.defineProperty(this, 'Ctrl', {get: () => Ctrl, set: value => Ctrl = value})
63
+ Object.defineProperty(this, 'Ctrl', { get: () => Ctrl, set: value => Ctrl = value })
63
64
  let name = spec.name || undefined;
64
- Object.defineProperty(this, 'name', {get: () => name, set: value => name = value})
65
+ Object.defineProperty(this, 'name', { get: () => name, set: value => name = value })
65
66
  this.__type_name = __type_name || 'server';
66
67
  const resource_pool = this.resource_pool = new Server_Resource_Pool({
67
68
  'access': {
@@ -92,20 +93,20 @@ class JSGUI_Single_Process_Server extends Evented_Class {
92
93
  if (Ctrl) {
93
94
 
94
95
 
95
- const wp_app = new Webpage({content: Ctrl});
96
+ const wp_app = new Webpage({ content: Ctrl });
97
+
98
+ const opts_wp_publisher = {
99
+ 'webpage': wp_app
100
+
101
+ };
102
+ if (bundler_config !== undefined) opts_wp_publisher.bundler = bundler_config;
96
103
 
97
- const opts_wp_publisher = {
98
- 'webpage': wp_app
99
-
100
- };
101
- if (bundler_config !== undefined) opts_wp_publisher.bundler = bundler_config;
102
-
103
- if (this.debug) {
104
- opts_wp_publisher.debug = this.debug;
105
- }
104
+ if (this.debug) {
105
+ opts_wp_publisher.debug = this.debug;
106
+ }
106
107
 
107
- if (disk_path_client_js) opts_wp_publisher.src_path_client_js = disk_path_client_js;
108
- if (style_config !== undefined) opts_wp_publisher.style = style_config;
108
+ if (disk_path_client_js) opts_wp_publisher.src_path_client_js = disk_path_client_js;
109
+ if (style_config !== undefined) opts_wp_publisher.style = style_config;
109
110
 
110
111
 
111
112
 
@@ -122,7 +123,7 @@ class JSGUI_Single_Process_Server extends Evented_Class {
122
123
 
123
124
  for (const bundle_item of wp_ready_res._arr) {
124
125
  //console.log('Object.keys(bundle_item)', Object.keys(bundle_item));
125
- const {type, extension, text, route, response_buffers, response_headers} = bundle_item;
126
+ const { type, extension, text, route, response_buffers, response_headers } = bundle_item;
126
127
  const bundle_item_http_responder = new Static_Route_HTTP_Responder(bundle_item);
127
128
 
128
129
 
@@ -165,18 +166,18 @@ class JSGUI_Single_Process_Server extends Evented_Class {
165
166
  const ws_app = this.app = this.website = new Website(opts_website);
166
167
  // Be able to treat Webpage as an app?
167
168
 
168
- const opts_ws_publisher = {
169
- 'website': ws_app
170
- };
171
- if (disk_path_client_js) {
172
- opts_ws_publisher.disk_path_client_js = disk_path_client_js;
173
- }
174
- if (bundler_config !== undefined) {
175
- opts_ws_publisher.bundler = bundler_config;
176
- }
177
- if (style_config !== undefined) {
178
- opts_ws_publisher.style = style_config;
179
- }
169
+ const opts_ws_publisher = {
170
+ 'website': ws_app
171
+ };
172
+ if (disk_path_client_js) {
173
+ opts_ws_publisher.disk_path_client_js = disk_path_client_js;
174
+ }
175
+ if (bundler_config !== undefined) {
176
+ opts_ws_publisher.bundler = bundler_config;
177
+ }
178
+ if (style_config !== undefined) {
179
+ opts_ws_publisher.style = style_config;
180
+ }
180
181
  const ws_publisher = new HTTP_Website_Publisher(opts_ws_publisher);
181
182
  this._ws_publisher = ws_publisher;
182
183
  ws_publisher.on('ready', () => {
@@ -191,7 +192,7 @@ class JSGUI_Single_Process_Server extends Evented_Class {
191
192
  });
192
193
  }
193
194
 
194
-
195
+
195
196
  Object.defineProperty(this, 'router', { get: () => server_router })
196
197
  }
197
198
 
@@ -200,7 +201,7 @@ class JSGUI_Single_Process_Server extends Evented_Class {
200
201
  // Possibly ensure it exists.
201
202
  //const fn_publisher = this.function_publisher;
202
203
  //fn_publisher.add(name, fn);
203
- const fpub = new HTTP_Function_Publisher({name, fn});
204
+ const fpub = new HTTP_Function_Publisher({ name, fn });
204
205
 
205
206
  this.function_publishers = this.function_publishers || [];
206
207
  this.function_publishers.push(fpub);
@@ -208,11 +209,24 @@ class JSGUI_Single_Process_Server extends Evented_Class {
208
209
  this.server_router.set_route('/api/' + name, fpub, fpub.handle_http);
209
210
  }
210
211
 
212
+ publish_observable(route, obs, options = {}) {
213
+ const publisher = new HTTP_Observable_Publisher({
214
+ obs,
215
+ ...options
216
+ });
217
+ this.server_router.set_route(route, publisher, publisher.handle_http);
218
+ return publisher;
219
+ }
220
+
221
+ publishObservable(route, obs, options) {
222
+ return this.publish_observable(route, obs, options);
223
+ }
224
+
211
225
 
212
226
  get resource_names() {
213
227
  return this.resource_pool.resource_names;
214
228
  }
215
- 'start' (port, callback, fnProcessRequest) {
229
+ 'start'(port, callback, fnProcessRequest) {
216
230
  if (tof(port) !== 'number') {
217
231
  console.log('Invalid port:', port);
218
232
  console.trace();
@@ -233,7 +247,7 @@ class JSGUI_Single_Process_Server extends Evented_Class {
233
247
  if (err) {
234
248
  callback(err);
235
249
  } else {
236
- // NEW: Filter addresses by allowed_addresses if specified.
250
+ // NEW: Filter addresses by allowed_addresses if specified.
237
251
  let arr_ipv4_addresses = [];
238
252
  each(net, (arr_addresses, name) => {
239
253
  each(arr_addresses, (obj_address) => {
@@ -245,33 +259,33 @@ class JSGUI_Single_Process_Server extends Evented_Class {
245
259
  if (this.allowed_addresses && this.allowed_addresses.length) {
246
260
  arr_ipv4_addresses = arr_ipv4_addresses.filter(a => this.allowed_addresses.indexOf(a) > -1);
247
261
  }
248
- arr_ipv4_addresses = [...new Set(arr_ipv4_addresses)];
249
- console.log('IPv4 addresses to bind:', arr_ipv4_addresses);
250
- let num_to_start = arr_ipv4_addresses.length;
251
- let started_count = 0;
252
- let last_error = null;
253
- let ready_raised = false;
254
- if (num_to_start === 0) {
255
- callback('No allowed network interfaces found.');
256
- return;
257
- }
258
- const finalize_start = (err) => {
259
- if (num_to_start !== 0) return;
260
- if (started_count > 0) {
261
- if (!ready_raised) {
262
- console.log('Server ready');
263
- this.raise('ready');
264
- ready_raised = true;
265
- }
266
- if (callback) callback(null, true);
267
- return;
268
- }
269
- const final_error = err || last_error || new Error('No servers started.');
270
- if (callback) callback(final_error);
271
- };
272
- const respond_not_found = (res) => {
273
- if (!res.headersSent) {
274
- const body = 'Not Found';
262
+ arr_ipv4_addresses = [...new Set(arr_ipv4_addresses)];
263
+ console.log('IPv4 addresses to bind:', arr_ipv4_addresses);
264
+ let num_to_start = arr_ipv4_addresses.length;
265
+ let started_count = 0;
266
+ let last_error = null;
267
+ let ready_raised = false;
268
+ if (num_to_start === 0) {
269
+ callback('No allowed network interfaces found.');
270
+ return;
271
+ }
272
+ const finalize_start = (err) => {
273
+ if (num_to_start !== 0) return;
274
+ if (started_count > 0) {
275
+ if (!ready_raised) {
276
+ console.log('Server ready');
277
+ this.raise('ready');
278
+ ready_raised = true;
279
+ }
280
+ if (callback) callback(null, true);
281
+ return;
282
+ }
283
+ const final_error = err || last_error || new Error('No servers started.');
284
+ if (callback) callback(final_error);
285
+ };
286
+ const respond_not_found = (res) => {
287
+ if (!res.headersSent) {
288
+ const body = 'Not Found';
275
289
  res.statusCode = 404;
276
290
  res.setHeader('Content-Type', 'text/plain; charset=utf-8');
277
291
  res.setHeader('Content-Length', Buffer.byteLength(body));
@@ -326,70 +340,70 @@ class JSGUI_Single_Process_Server extends Evented_Class {
326
340
  if (this.https_options) {
327
341
  each(arr_ipv4_addresses, (ipv4_address) => {
328
342
  try {
329
- var https_server = https.createServer(this.https_options, function(req, res) {
343
+ var https_server = https.createServer(this.https_options, function (req, res) {
330
344
  process_request(req, res);
331
345
  });
332
346
  this.http_servers.push(https_server);
333
- https_server.on('error', (err) => {
334
- last_error = err;
335
- if (err.code === 'EACCES') {
336
- console.error('Permission denied:', err.message);
337
- } else if (err.code === 'EADDRINUSE') {
338
- console.error(`Address ${ipv4_address}:${port} already in use; skipping.`);
339
- } else {
340
- console.error('https_server error:', err);
341
- }
342
- num_to_start--;
343
- finalize_start(err);
344
- });
345
- https_server.timeout = 10800000;
346
- https_server.listen(port, ipv4_address, () => {
347
- console.log('* Server running at https://' + ipv4_address + ':' + port + '/');
348
- started_count++;
349
- num_to_start--;
350
- finalize_start(null);
351
- });
352
- } catch (err) {
353
- console.log('https_server err', err);
354
- num_to_start--;
355
- finalize_start(err);
356
- }
357
- });
358
- } else {
359
- each(arr_ipv4_addresses, (ipv4_address) => {
360
- try {
361
- var http_server = http.createServer(function(req, res) {
362
- process_request(req, res);
363
- });
364
- this.http_servers.push(http_server);
365
- http_server.on('error', (err) => {
366
- last_error = err;
367
- if (err.code === 'EACCES') {
368
- console.error('Permission denied:', err.message);
369
- } else if (err.code === 'EADDRINUSE') {
370
- console.error(`Address ${ipv4_address}:${port} already in use; skipping.`);
371
- } else {
372
- console.error('http_server error:', err);
373
- }
374
- num_to_start--;
375
- finalize_start(err);
376
- });
377
- http_server.timeout = 10800000;
378
- http_server.listen(port, ipv4_address, () => {
379
- console.log('* Server running at http://' + ipv4_address + ':' + port + '/');
380
- started_count++;
381
- num_to_start--;
382
- finalize_start(null);
383
- });
384
- } catch (err) {
385
- console.log('http_server err', err);
386
- num_to_start--;
387
- finalize_start(err);
388
- }
389
- });
390
- }
391
- }
392
- });
347
+ https_server.on('error', (err) => {
348
+ last_error = err;
349
+ if (err.code === 'EACCES') {
350
+ console.error('Permission denied:', err.message);
351
+ } else if (err.code === 'EADDRINUSE') {
352
+ console.error(`Address ${ipv4_address}:${port} already in use; skipping.`);
353
+ } else {
354
+ console.error('https_server error:', err);
355
+ }
356
+ num_to_start--;
357
+ finalize_start(err);
358
+ });
359
+ https_server.timeout = 10800000;
360
+ https_server.listen(port, ipv4_address, () => {
361
+ console.log('* Server running at https://' + ipv4_address + ':' + port + '/');
362
+ started_count++;
363
+ num_to_start--;
364
+ finalize_start(null);
365
+ });
366
+ } catch (err) {
367
+ console.log('https_server err', err);
368
+ num_to_start--;
369
+ finalize_start(err);
370
+ }
371
+ });
372
+ } else {
373
+ each(arr_ipv4_addresses, (ipv4_address) => {
374
+ try {
375
+ var http_server = http.createServer(function (req, res) {
376
+ process_request(req, res);
377
+ });
378
+ this.http_servers.push(http_server);
379
+ http_server.on('error', (err) => {
380
+ last_error = err;
381
+ if (err.code === 'EACCES') {
382
+ console.error('Permission denied:', err.message);
383
+ } else if (err.code === 'EADDRINUSE') {
384
+ console.error(`Address ${ipv4_address}:${port} already in use; skipping.`);
385
+ } else {
386
+ console.error('http_server error:', err);
387
+ }
388
+ num_to_start--;
389
+ finalize_start(err);
390
+ });
391
+ http_server.timeout = 10800000;
392
+ http_server.listen(port, ipv4_address, () => {
393
+ console.log('* Server running at http://' + ipv4_address + ':' + port + '/');
394
+ started_count++;
395
+ num_to_start--;
396
+ finalize_start(null);
397
+ });
398
+ } catch (err) {
399
+ console.log('http_server err', err);
400
+ num_to_start--;
401
+ finalize_start(err);
402
+ }
403
+ });
404
+ }
405
+ }
406
+ });
393
407
  }
394
408
  });
395
409
  }
@@ -441,64 +455,64 @@ if (require.main === module) {
441
455
  }
442
456
  current();
443
457
 
444
- } else {}
458
+ } else { }
445
459
 
446
460
  //
447
461
 
448
462
  const summary = {
449
- "classes": [
450
- "JSGUI_Single_Process_Server",
451
- "Server_Resource_Pool",
452
- "Router",
453
- "Website_Resource",
454
- "Server_Page_Context",
455
- "Web_Admin_Page_Control",
456
- "Web_Admin_Panel_Control",
457
- "Website",
458
- "HTTP_Website_Publisher",
459
- "Webpage"
460
- ],
461
- "methods": {
462
- "JSGUI_Single_Process_Server": [
463
- "constructor",
464
- "start",
465
- "stop"
466
- ],
467
- "Server_Resource_Pool": [
468
- "constructor"
469
- ],
470
- "Router": [
471
- "constructor",
472
- "set_route",
473
- "unset_route"
474
- ],
475
- "Website_Resource": [
476
- "constructor",
477
- "process"
478
- ],
479
- "Server_Page_Context": [
480
- "constructor",
481
- "respond_string"
482
- ],
483
- "Web_Admin_Page_Control": [
484
- "constructor"
485
- ],
486
- "Web_Admin_Panel_Control": [
487
- "constructor"
488
- ],
489
- "Website": [
490
- "constructor",
491
- "add_page",
492
- "add_page_resource",
493
- "add_page_resource_from_webpage"
494
- ],
495
- "HTTP_Website_Publisher": [
496
- "constructor"
497
- ],
498
- "Webpage": [
499
- "constructor"
500
- ]
501
- }
463
+ "classes": [
464
+ "JSGUI_Single_Process_Server",
465
+ "Server_Resource_Pool",
466
+ "Router",
467
+ "Website_Resource",
468
+ "Server_Page_Context",
469
+ "Web_Admin_Page_Control",
470
+ "Web_Admin_Panel_Control",
471
+ "Website",
472
+ "HTTP_Website_Publisher",
473
+ "Webpage"
474
+ ],
475
+ "methods": {
476
+ "JSGUI_Single_Process_Server": [
477
+ "constructor",
478
+ "start",
479
+ "stop"
480
+ ],
481
+ "Server_Resource_Pool": [
482
+ "constructor"
483
+ ],
484
+ "Router": [
485
+ "constructor",
486
+ "set_route",
487
+ "unset_route"
488
+ ],
489
+ "Website_Resource": [
490
+ "constructor",
491
+ "process"
492
+ ],
493
+ "Server_Page_Context": [
494
+ "constructor",
495
+ "respond_string"
496
+ ],
497
+ "Web_Admin_Page_Control": [
498
+ "constructor"
499
+ ],
500
+ "Web_Admin_Panel_Control": [
501
+ "constructor"
502
+ ],
503
+ "Website": [
504
+ "constructor",
505
+ "add_page",
506
+ "add_page_resource",
507
+ "add_page_resource_from_webpage"
508
+ ],
509
+ "HTTP_Website_Publisher": [
510
+ "constructor"
511
+ ],
512
+ "Webpage": [
513
+ "constructor"
514
+ ]
515
+ }
502
516
  }
503
517
 
504
518
  JSGUI_Single_Process_Server.summary = summary;