jsgui3-server 0.0.150 → 0.0.152
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/instructions/copilot.instructions.md +1 -0
- package/AGENTS.md +2 -0
- package/README.md +89 -13
- package/admin-ui/v1/controls/admin_shell.js +702 -669
- package/admin-ui/v1/server.js +14 -1
- package/docs/api-reference.md +504 -306
- package/docs/books/creating-a-new-admin-ui/README.md +20 -20
- package/docs/books/website-design/01-introduction.md +73 -0
- package/docs/books/website-design/02-current-state.md +195 -0
- package/docs/books/website-design/03-base-class.md +181 -0
- package/docs/books/website-design/04-webpage.md +307 -0
- package/docs/books/website-design/05-website.md +456 -0
- package/docs/books/website-design/06-pages-storage.md +170 -0
- package/docs/books/website-design/07-api-layer.md +285 -0
- package/docs/books/website-design/08-server-integration.md +271 -0
- package/docs/books/website-design/09-cross-agent-review.md +190 -0
- package/docs/books/website-design/10-open-questions.md +196 -0
- package/docs/books/website-design/11-converged-recommendation.md +205 -0
- package/docs/books/website-design/12-content-model.md +395 -0
- package/docs/books/website-design/13-webpage-module-spec.md +404 -0
- package/docs/books/website-design/14-website-module-spec.md +541 -0
- package/docs/books/website-design/15-multi-repo-plan.md +275 -0
- package/docs/books/website-design/16-minimal-first.md +203 -0
- package/docs/books/website-design/17-implementation-report-codex.md +81 -0
- package/docs/books/website-design/README.md +43 -0
- package/docs/comprehensive-documentation.md +220 -220
- package/docs/configuration-reference.md +281 -204
- package/docs/middleware-guide.md +236 -0
- package/docs/proposals/jsgui3-website-and-webpage-design-jsgui3-server-support.md +257 -0
- package/docs/proposals/jsgui3-website-and-webpage-design-review.md +73 -0
- package/docs/proposals/jsgui3-website-and-webpage-design.md +732 -0
- package/docs/swagger.md +316 -0
- package/docs/system-architecture.md +24 -18
- package/examples/controls/1) window/server.js +6 -1
- package/examples/controls/21) mvvm and declarative api/check.js +94 -0
- package/examples/controls/21) mvvm and declarative api/check_output.txt +25 -0
- package/examples/controls/21) mvvm and declarative api/check_output_2.txt +27 -0
- package/examples/controls/21) mvvm and declarative api/client.js +241 -0
- declarative api/e2e-screenshot-1-name-change.png +0 -0
- declarative api/e2e-screenshot-2-toggled.png +0 -0
- declarative api/e2e-screenshot-3-final.png +0 -0
- declarative api/e2e-screenshot-final.png +0 -0
- package/examples/controls/21) mvvm and declarative api/e2e-test.js +175 -0
- package/examples/controls/21) mvvm and declarative api/out.html +1 -0
- package/examples/controls/21) mvvm and declarative api/page_out.html +1 -0
- package/examples/controls/21) mvvm and declarative api/server.js +18 -0
- package/examples/data-views/01) query-endpoint/server.js +61 -0
- package/labs/website-design/001-base-class-overhead/check.js +162 -0
- package/labs/website-design/002-pages-storage/check.js +244 -0
- package/labs/website-design/002-pages-storage/results.txt +0 -0
- package/labs/website-design/003-type-detection/check.js +193 -0
- package/labs/website-design/003-type-detection/results.txt +0 -0
- package/labs/website-design/004-two-stage-validation/check.js +314 -0
- package/labs/website-design/004-two-stage-validation/results.txt +0 -0
- package/labs/website-design/005-normalize-input/check.js +303 -0
- package/labs/website-design/006-serve-website-spike/check.js +290 -0
- package/labs/website-design/README.md +34 -0
- package/labs/website-design/manifest.json +68 -0
- package/labs/website-design/run-all.js +60 -0
- package/middleware/compression.js +217 -0
- package/middleware/index.js +15 -0
- package/middleware/json-body.js +126 -0
- package/module.js +3 -0
- package/openapi.js +474 -0
- package/package.json +11 -8
- package/publishers/Publishers.js +6 -5
- package/publishers/http-function-publisher.js +135 -126
- package/publishers/http-webpage-publisher.js +89 -11
- package/publishers/query-publisher.js +116 -0
- package/publishers/swagger-publisher.js +203 -0
- package/publishers/swagger-ui.js +578 -0
- package/resources/adapters/array-adapter.js +143 -0
- package/resources/query-resource.js +131 -0
- package/serve-factory.js +756 -18
- package/server.js +502 -123
- package/tests/README.md +23 -1
- package/tests/admin-ui-jsgui-controls.test.js +16 -1
- package/tests/helpers/playwright-e2e-harness.js +326 -0
- package/tests/openapi.test.js +319 -0
- package/tests/playwright-smoke.test.js +134 -0
- package/tests/publish-enhancements.test.js +673 -0
- package/tests/query-publisher.test.js +430 -0
- package/tests/quick-json-body-test.js +169 -0
- package/tests/serve.test.js +425 -122
- package/tests/swagger-publisher.test.js +1076 -0
- package/tests/test-runner.js +1 -0
package/docs/api-reference.md
CHANGED
|
@@ -32,30 +32,30 @@ Server.serve(options?: ServerOptions): Promise<Server>
|
|
|
32
32
|
- `DiscoveryError`: Cannot find client files or controls
|
|
33
33
|
- `BindingError`: Cannot bind to specified host/port
|
|
34
34
|
|
|
35
|
-
**Example:**
|
|
36
|
-
```javascript
|
|
37
|
-
const server = await Server.serve({
|
|
38
|
-
port: 3000,
|
|
39
|
-
ctrl: MyControl,
|
|
40
|
-
resources: {
|
|
41
|
-
worker_direct: {
|
|
42
|
-
type: 'process',
|
|
43
|
-
command: process.execPath,
|
|
44
|
-
args: ['worker.js']
|
|
45
|
-
},
|
|
46
|
-
remote_worker: {
|
|
47
|
-
type: 'remote',
|
|
48
|
-
host: '127.0.0.1',
|
|
49
|
-
port: 3400
|
|
50
|
-
}
|
|
51
|
-
},
|
|
52
|
-
events: true
|
|
53
|
-
});
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
**Serve-specific options:**
|
|
57
|
-
- `resources`: Registers managed resources (in-process resource objects, local process resources, remote HTTP process resources).
|
|
58
|
-
- `events`: Enables built-in SSE publisher for resource lifecycle events (`/events` by default).
|
|
35
|
+
**Example:**
|
|
36
|
+
```javascript
|
|
37
|
+
const server = await Server.serve({
|
|
38
|
+
port: 3000,
|
|
39
|
+
ctrl: MyControl,
|
|
40
|
+
resources: {
|
|
41
|
+
worker_direct: {
|
|
42
|
+
type: 'process',
|
|
43
|
+
command: process.execPath,
|
|
44
|
+
args: ['worker.js']
|
|
45
|
+
},
|
|
46
|
+
remote_worker: {
|
|
47
|
+
type: 'remote',
|
|
48
|
+
host: '127.0.0.1',
|
|
49
|
+
port: 3400
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
events: true
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Serve-specific options:**
|
|
57
|
+
- `resources`: Registers managed resources (in-process resource objects, local process resources, remote HTTP process resources).
|
|
58
|
+
- `events`: Enables built-in SSE publisher for resource lifecycle events (`/events` by default).
|
|
59
59
|
|
|
60
60
|
### Server Constructor
|
|
61
61
|
|
|
@@ -71,42 +71,56 @@ new Server(options?: ServerOptions)
|
|
|
71
71
|
|
|
72
72
|
**Returns:** Server instance
|
|
73
73
|
|
|
74
|
-
**Events:**
|
|
75
|
-
- `'ready'`: Emitted when bundling is complete
|
|
76
|
-
- `'started'`: Emitted when HTTP server is listening
|
|
77
|
-
- `'error'`: Emitted on server errors
|
|
78
|
-
|
|
79
|
-
### Module Exports
|
|
80
|
-
|
|
81
|
-
```javascript
|
|
82
|
-
const jsgui = require('jsgui3-server');
|
|
83
|
-
|
|
84
|
-
// Top-level exports
|
|
85
|
-
jsgui.Process_Resource;
|
|
86
|
-
jsgui.Remote_Process_Resource;
|
|
87
|
-
jsgui.HTTP_SSE_Publisher;
|
|
88
|
-
|
|
89
|
-
// Resource namespace aliases
|
|
90
|
-
jsgui.Resource.Process;
|
|
91
|
-
jsgui.Resource.Remote_Process;
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## Server Instance Methods
|
|
95
|
-
|
|
96
|
-
### server.start(port, callback)
|
|
74
|
+
**Events:**
|
|
75
|
+
- `'ready'`: Emitted when bundling is complete
|
|
76
|
+
- `'started'`: Emitted when HTTP server is listening
|
|
77
|
+
- `'error'`: Emitted on server errors
|
|
78
|
+
|
|
79
|
+
### Module Exports
|
|
80
|
+
|
|
81
|
+
```javascript
|
|
82
|
+
const jsgui = require('jsgui3-server');
|
|
83
|
+
|
|
84
|
+
// Top-level exports
|
|
85
|
+
jsgui.Process_Resource;
|
|
86
|
+
jsgui.Remote_Process_Resource;
|
|
87
|
+
jsgui.HTTP_SSE_Publisher;
|
|
88
|
+
|
|
89
|
+
// Resource namespace aliases
|
|
90
|
+
jsgui.Resource.Process;
|
|
91
|
+
jsgui.Resource.Remote_Process;
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Server Instance Methods
|
|
95
|
+
|
|
96
|
+
### server.start(port, callback, options)
|
|
97
97
|
|
|
98
98
|
Starts the HTTP server (legacy API).
|
|
99
99
|
|
|
100
100
|
**Signature:**
|
|
101
101
|
```javascript
|
|
102
|
-
server.start(
|
|
102
|
+
server.start(
|
|
103
|
+
port?: number,
|
|
104
|
+
callback?: (err?: Error) => void,
|
|
105
|
+
options?: {
|
|
106
|
+
on_port_conflict?: 'error' | 'auto-loopback'
|
|
107
|
+
}
|
|
108
|
+
): void
|
|
103
109
|
```
|
|
104
110
|
|
|
105
111
|
**Parameters:**
|
|
106
112
|
- `port` (number, optional): Port to listen on (default: 8080)
|
|
107
113
|
- `callback` (function, optional): Called when server starts or fails
|
|
114
|
+
- `options` (object, optional): Startup behavior options
|
|
115
|
+
- `on_port_conflict: 'error' | 'auto-loopback'`
|
|
116
|
+
- `error` (default): Return startup error as usual.
|
|
117
|
+
- `auto-loopback`: If all requested interface binds fail with `EADDRINUSE`,
|
|
118
|
+
retry once on `127.0.0.1` using a free port.
|
|
108
119
|
|
|
109
|
-
|
|
120
|
+
When startup fails, the returned error may include `error.startup_diagnostics`
|
|
121
|
+
containing attempted addresses and per-address errors.
|
|
122
|
+
|
|
123
|
+
### server.publish(route, handler)
|
|
110
124
|
|
|
111
125
|
Adds an API endpoint (legacy API).
|
|
112
126
|
|
|
@@ -115,53 +129,227 @@ Adds an API endpoint (legacy API).
|
|
|
115
129
|
server.publish(route: string, handler: Function): void
|
|
116
130
|
```
|
|
117
131
|
|
|
118
|
-
**Parameters:**
|
|
119
|
-
- `route` (string): Route path (automatically prefixed with `/api/`)
|
|
120
|
-
- `handler` (Function): Request handler function
|
|
121
|
-
|
|
122
|
-
### server.publish_observable(route, observable, options)
|
|
123
|
-
|
|
124
|
-
Adds an observable-backed SSE endpoint.
|
|
125
|
-
|
|
126
|
-
**Signature:**
|
|
127
|
-
```javascript
|
|
128
|
-
server.publish_observable(route: string, observable: Observable, options?: object): HTTP_Observable_Publisher
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
**Parameters:**
|
|
132
|
-
- `route` (string): Route path. If it does not start with `/`, it is prefixed with `/api/`.
|
|
133
|
-
- `observable` (Observable): Source observable stream.
|
|
134
|
-
- `options` (object, optional): Publisher options.
|
|
135
|
-
|
|
136
|
-
**Returns:** `HTTP_Observable_Publisher` instance.
|
|
137
|
-
|
|
138
|
-
**Alias:** `server.publishObservable(route, observable, options)`
|
|
139
|
-
|
|
140
|
-
### server.close(callback)
|
|
141
|
-
|
|
142
|
-
Stops managed resources and closes all bound HTTP servers.
|
|
143
|
-
|
|
144
|
-
**Signature:**
|
|
145
|
-
```javascript
|
|
146
|
-
server.close(callback?: (err?: Error | null) => void): void
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
**Behavior:**
|
|
150
|
-
- Calls `resource_pool.stop()` when available
|
|
151
|
-
- Stops `sse_publisher` when present
|
|
152
|
-
- Closes all HTTP listeners
|
|
153
|
-
|
|
154
|
-
### server.
|
|
155
|
-
|
|
156
|
-
|
|
132
|
+
**Parameters:**
|
|
133
|
+
- `route` (string): Route path (automatically prefixed with `/api/`)
|
|
134
|
+
- `handler` (Function): Request handler function
|
|
135
|
+
|
|
136
|
+
### server.publish_observable(route, observable, options)
|
|
137
|
+
|
|
138
|
+
Adds an observable-backed SSE endpoint.
|
|
139
|
+
|
|
140
|
+
**Signature:**
|
|
141
|
+
```javascript
|
|
142
|
+
server.publish_observable(route: string, observable: Observable, options?: object): HTTP_Observable_Publisher
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Parameters:**
|
|
146
|
+
- `route` (string): Route path. If it does not start with `/`, it is prefixed with `/api/`.
|
|
147
|
+
- `observable` (Observable): Source observable stream.
|
|
148
|
+
- `options` (object, optional): Publisher options.
|
|
149
|
+
|
|
150
|
+
**Returns:** `HTTP_Observable_Publisher` instance.
|
|
151
|
+
|
|
152
|
+
**Alias:** `server.publishObservable(route, observable, options)`
|
|
153
|
+
|
|
154
|
+
### server.close(callback)
|
|
155
|
+
|
|
156
|
+
Stops managed resources and closes all bound HTTP servers.
|
|
157
|
+
|
|
158
|
+
**Signature:**
|
|
159
|
+
```javascript
|
|
160
|
+
server.close(callback?: (err?: Error | null) => void): void
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Behavior:**
|
|
164
|
+
- Calls `resource_pool.stop()` when available
|
|
165
|
+
- Stops `sse_publisher` when present
|
|
166
|
+
- Closes all HTTP listeners
|
|
167
|
+
|
|
168
|
+
### server.get_listening_endpoints()
|
|
169
|
+
|
|
170
|
+
Returns the active listener endpoints (protocol, host, port, url) for the
|
|
171
|
+
current process. Useful when startup falls back from a requested fixed port to
|
|
172
|
+
an auto-selected loopback port.
|
|
173
|
+
|
|
174
|
+
**Signature:**
|
|
175
|
+
```javascript
|
|
176
|
+
server.get_listening_endpoints(): Array<{
|
|
177
|
+
protocol: 'http' | 'https';
|
|
178
|
+
host: string;
|
|
179
|
+
port: number;
|
|
180
|
+
url: string;
|
|
181
|
+
}>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Example:**
|
|
185
|
+
```javascript
|
|
186
|
+
server.start(52000, (err) => {
|
|
187
|
+
if (err) throw err;
|
|
188
|
+
console.log('Listening at', server.get_primary_endpoint());
|
|
189
|
+
}, {
|
|
190
|
+
on_port_conflict: 'auto-loopback'
|
|
191
|
+
});
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### server.get_primary_endpoint()
|
|
195
|
+
|
|
196
|
+
Returns the primary endpoint URL string (first endpoint) or `null` if the
|
|
197
|
+
server is not listening.
|
|
198
|
+
|
|
199
|
+
**Signature:**
|
|
200
|
+
```javascript
|
|
201
|
+
server.get_primary_endpoint(): string | null
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**Example:**
|
|
205
|
+
```javascript
|
|
206
|
+
const url = server.get_primary_endpoint();
|
|
207
|
+
if (url) {
|
|
208
|
+
console.log('Primary endpoint:', url);
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### server.print_endpoints(options)
|
|
213
|
+
|
|
214
|
+
Prints listening endpoint URLs and returns the printed lines.
|
|
215
|
+
|
|
216
|
+
**Signature:**
|
|
217
|
+
```javascript
|
|
218
|
+
server.print_endpoints(options?: {
|
|
219
|
+
logger?: (line: string) => void;
|
|
220
|
+
include_index?: boolean;
|
|
221
|
+
prefix?: string;
|
|
222
|
+
}): string[]
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Parameters:**
|
|
226
|
+
- `options.logger` (function, optional): Line logger (default: `console.log`)
|
|
227
|
+
- `options.include_index` (boolean, optional): Include endpoint index in output
|
|
228
|
+
- `options.prefix` (string, optional): Prefix text (default: `"listening endpoint"`)
|
|
229
|
+
|
|
230
|
+
**Example:**
|
|
231
|
+
```javascript
|
|
232
|
+
server.start(52000, (err) => {
|
|
233
|
+
if (err) throw err;
|
|
234
|
+
server.print_endpoints({ include_index: true });
|
|
235
|
+
}, {
|
|
236
|
+
on_port_conflict: 'auto-loopback'
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### server.get_startup_diagnostics()
|
|
241
|
+
|
|
242
|
+
Returns startup diagnostics information or `null` when unavailable.
|
|
243
|
+
|
|
244
|
+
**Signature:**
|
|
245
|
+
```javascript
|
|
246
|
+
server.get_startup_diagnostics(): {
|
|
247
|
+
requested_port: number;
|
|
248
|
+
fallback_port?: number;
|
|
249
|
+
fallback_host?: string;
|
|
250
|
+
addresses_attempted: string[];
|
|
251
|
+
errors_by_address: Record<string, { code?: string; message?: string }>;
|
|
252
|
+
} | null
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**Example:**
|
|
256
|
+
```javascript
|
|
257
|
+
server.start(52000, (err) => {
|
|
258
|
+
if (err) {
|
|
259
|
+
console.error(server.get_startup_diagnostics());
|
|
260
|
+
throw err;
|
|
261
|
+
}
|
|
262
|
+
console.log(server.get_startup_diagnostics());
|
|
263
|
+
}, {
|
|
264
|
+
on_port_conflict: 'auto-loopback'
|
|
265
|
+
});
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### server.use(fn)
|
|
269
|
+
|
|
270
|
+
Register middleware to run before every request is routed. Middleware is executed
|
|
271
|
+
in registration order. The chain runs to completion before the router processes
|
|
272
|
+
the request.
|
|
157
273
|
|
|
158
274
|
**Signature:**
|
|
159
275
|
```javascript
|
|
160
|
-
server.use(
|
|
276
|
+
server.use(fn: Function): Server // returns `this` for chaining
|
|
161
277
|
```
|
|
162
278
|
|
|
163
279
|
**Parameters:**
|
|
164
|
-
- `
|
|
280
|
+
- `fn` (Function): Middleware function with signature `(req, res, next) => void`
|
|
281
|
+
- `req` — Node.js `http.IncomingMessage`
|
|
282
|
+
- `res` — Node.js `http.ServerResponse`
|
|
283
|
+
- `next` — Call `next()` to continue to the next middleware / router.
|
|
284
|
+
Call `next(err)` to skip remaining middleware and trigger the error handler
|
|
285
|
+
(500 response).
|
|
286
|
+
|
|
287
|
+
**Returns:** The server instance (for chaining).
|
|
288
|
+
|
|
289
|
+
**Throws:** `Error` if `fn` is not a function.
|
|
290
|
+
|
|
291
|
+
**Example:**
|
|
292
|
+
```javascript
|
|
293
|
+
const { compression } = require('jsgui3-server/middleware');
|
|
294
|
+
|
|
295
|
+
server
|
|
296
|
+
.use((req, res, next) => {
|
|
297
|
+
console.log(`${req.method} ${req.url}`);
|
|
298
|
+
next();
|
|
299
|
+
})
|
|
300
|
+
.use(compression());
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**Execution order:**
|
|
304
|
+
```
|
|
305
|
+
HTTP Request → middleware[0] → middleware[1] → … → router
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
If no middleware is registered, the router is called directly with zero overhead.
|
|
309
|
+
|
|
310
|
+
**See also:** [Middleware Guide](middleware-guide.md) for response-wrapping
|
|
311
|
+
patterns, custom middleware examples, and the built-in compression reference.
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
### Built-in Middleware
|
|
316
|
+
|
|
317
|
+
#### `compression([options])`
|
|
318
|
+
|
|
319
|
+
Response-compression middleware. Transparently compresses response bodies
|
|
320
|
+
(gzip / deflate / brotli) when the client supports it and the content type
|
|
321
|
+
is compressible.
|
|
322
|
+
|
|
323
|
+
```javascript
|
|
324
|
+
const { compression } = require('jsgui3-server/middleware');
|
|
325
|
+
server.use(compression()); // defaults
|
|
326
|
+
server.use(compression({ threshold: 512 })); // lower threshold
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
**Options:**
|
|
330
|
+
|
|
331
|
+
| Option | Type | Default | Description |
|
|
332
|
+
|-----------|--------|---------------------------|-------------------------------------------|
|
|
333
|
+
| `threshold` | number | `1024` | Minimum body size in bytes to compress |
|
|
334
|
+
| `level` | number | `Z_DEFAULT_COMPRESSION` | zlib compression level (1–9, or -1) |
|
|
335
|
+
|
|
336
|
+
**Encoding priority:** gzip → deflate → brotli
|
|
337
|
+
|
|
338
|
+
**Compressible types:** `application/json`, `text/html`, `text/plain`,
|
|
339
|
+
`text/css`, `text/xml`, `text/csv`, `text/javascript`,
|
|
340
|
+
`application/javascript`, `application/xml`, `application/xhtml+xml`,
|
|
341
|
+
`application/manifest+json`, `image/svg+xml`.
|
|
342
|
+
|
|
343
|
+
**Not compressed:** bodies below threshold, binary content types, responses
|
|
344
|
+
with an existing `Content-Encoding`, and streaming responses (`res.write()`
|
|
345
|
+
before `res.end()` — e.g. SSE).
|
|
346
|
+
|
|
347
|
+
**Access paths:**
|
|
348
|
+
```javascript
|
|
349
|
+
require('jsgui3-server/middleware').compression // direct
|
|
350
|
+
require('jsgui3-server').middleware.compression // via module
|
|
351
|
+
Server.middleware.compression // via class
|
|
352
|
+
```
|
|
165
353
|
|
|
166
354
|
## Port Utilities
|
|
167
355
|
|
|
@@ -507,7 +695,7 @@ Serves CSS files.
|
|
|
507
695
|
serve(request: IncomingMessage, response: ServerResponse): Promise<void>
|
|
508
696
|
```
|
|
509
697
|
|
|
510
|
-
### HTTP_API_Publisher
|
|
698
|
+
### HTTP_API_Publisher
|
|
511
699
|
|
|
512
700
|
Handles API endpoints.
|
|
513
701
|
|
|
@@ -525,162 +713,162 @@ new HTTP_API_Publisher(spec?: PublisherSpec)
|
|
|
525
713
|
Handles API requests.
|
|
526
714
|
|
|
527
715
|
**Signature:**
|
|
528
|
-
```javascript
|
|
529
|
-
serve(request: IncomingMessage, response: ServerResponse): Promise<void>
|
|
530
|
-
```
|
|
531
|
-
|
|
532
|
-
### HTTP_SSE_Publisher
|
|
533
|
-
|
|
534
|
-
General-purpose SSE publisher for explicit event fan-out.
|
|
535
|
-
|
|
536
|
-
**Extends:** `HTTP_Publisher`
|
|
537
|
-
|
|
538
|
-
**Constructor:**
|
|
539
|
-
```javascript
|
|
540
|
-
new HTTP_SSE_Publisher(spec?: {
|
|
541
|
-
name?: string,
|
|
542
|
-
keepaliveIntervalMs?: number,
|
|
543
|
-
maxClients?: number,
|
|
544
|
-
eventHistorySize?: number
|
|
545
|
-
})
|
|
546
|
-
```
|
|
547
|
-
|
|
548
|
-
**Methods:**
|
|
549
|
-
- `handle_http(req, res)`
|
|
550
|
-
- `broadcast(event_name, data_value)`
|
|
551
|
-
- `send(client_id, event_name, data_value)`
|
|
552
|
-
- `stop(callback?)`
|
|
553
|
-
|
|
554
|
-
**Properties:**
|
|
555
|
-
- `client_count` (number)
|
|
556
|
-
|
|
557
|
-
## Resource Classes
|
|
558
|
-
|
|
559
|
-
### Process_Resource
|
|
560
|
-
|
|
561
|
-
Represents a local process as a resource with a unified lifecycle API.
|
|
562
|
-
|
|
563
|
-
**Extends:** `Resource`
|
|
564
|
-
|
|
565
|
-
**Constructor:**
|
|
566
|
-
```javascript
|
|
567
|
-
new Process_Resource(spec?: {
|
|
568
|
-
name?: string,
|
|
569
|
-
command?: string,
|
|
570
|
-
args?: string[],
|
|
571
|
-
cwd?: string,
|
|
572
|
-
env?: object,
|
|
573
|
-
autoRestart?: boolean,
|
|
574
|
-
maxRestarts?: number,
|
|
575
|
-
processManager?: 'direct' | {
|
|
576
|
-
type: 'direct' | 'pm2',
|
|
577
|
-
pm2Path?: string,
|
|
578
|
-
ecosystem?: string
|
|
579
|
-
},
|
|
580
|
-
healthCheck?: {
|
|
581
|
-
type: 'http' | 'tcp' | 'custom',
|
|
582
|
-
url?: string,
|
|
583
|
-
host?: string,
|
|
584
|
-
port?: number,
|
|
585
|
-
fn?: Function,
|
|
586
|
-
intervalMs?: number,
|
|
587
|
-
timeoutMs?: number,
|
|
588
|
-
failuresBeforeUnhealthy?: number
|
|
589
|
-
}
|
|
590
|
-
})
|
|
591
|
-
```
|
|
592
|
-
|
|
593
|
-
**Core Methods:**
|
|
594
|
-
- `start(callback?)`
|
|
595
|
-
- `stop(callback?)`
|
|
596
|
-
- `restart(callback?)`
|
|
597
|
-
- `get_abstract()`
|
|
598
|
-
|
|
599
|
-
**Status:**
|
|
600
|
-
```javascript
|
|
601
|
-
{
|
|
602
|
-
state: 'stopped' | 'starting' | 'running' | 'stopping' | 'restarting' | 'crashed',
|
|
603
|
-
pid: number | null,
|
|
604
|
-
uptime: number,
|
|
605
|
-
restartCount: number,
|
|
606
|
-
lastHealthCheck: object | null,
|
|
607
|
-
memoryUsage: object | null,
|
|
608
|
-
processManager: { type: 'direct' | 'pm2' }
|
|
609
|
-
}
|
|
610
|
-
```
|
|
611
|
-
|
|
612
|
-
**Events:**
|
|
613
|
-
- `state_change`
|
|
614
|
-
- `stdout`
|
|
615
|
-
- `stderr`
|
|
616
|
-
- `exit`
|
|
617
|
-
- `health_check`
|
|
618
|
-
- `unhealthy`
|
|
619
|
-
- `crashed`
|
|
620
|
-
|
|
621
|
-
### Remote_Process_Resource
|
|
622
|
-
|
|
623
|
-
Represents a remote HTTP-controlled process using the same lifecycle-oriented API style as `Process_Resource`.
|
|
624
|
-
|
|
625
|
-
**Extends:** `Resource`
|
|
626
|
-
|
|
627
|
-
**Constructor:**
|
|
628
|
-
```javascript
|
|
629
|
-
new Remote_Process_Resource(spec?: {
|
|
630
|
-
name?: string,
|
|
631
|
-
host: string,
|
|
632
|
-
port: number,
|
|
633
|
-
protocol?: 'http' | 'https',
|
|
634
|
-
pollIntervalMs?: number,
|
|
635
|
-
httpTimeoutMs?: number,
|
|
636
|
-
historySize?: number,
|
|
637
|
-
unreachableFailuresBeforeEvent?: number,
|
|
638
|
-
endpoints?: {
|
|
639
|
-
status?: string,
|
|
640
|
-
start?: string,
|
|
641
|
-
stop?: string,
|
|
642
|
-
health?: string
|
|
643
|
-
}
|
|
644
|
-
})
|
|
645
|
-
```
|
|
646
|
-
|
|
647
|
-
**Core Methods:**
|
|
648
|
-
- `start(callback?)`
|
|
649
|
-
- `stop(callback?)`
|
|
650
|
-
- `restart(callback?)`
|
|
651
|
-
- `get_abstract()`
|
|
652
|
-
|
|
653
|
-
**Status:** Includes `state`, `pid`, `uptime`, `restartCount`, `lastHealthCheck`, `memoryUsage`, and `processManager: { type: 'remote' }`.
|
|
654
|
-
|
|
655
|
-
**Events:**
|
|
656
|
-
- `state_change`
|
|
657
|
-
- `unreachable`
|
|
658
|
-
- `recovered`
|
|
659
|
-
|
|
660
|
-
### Server_Resource_Pool
|
|
661
|
-
|
|
662
|
-
Server-specific resource pool with lifecycle orchestration and event forwarding.
|
|
663
|
-
|
|
664
|
-
**Extends:** `Resource_Pool`
|
|
665
|
-
|
|
666
|
-
**Methods:**
|
|
667
|
-
- `add(resource)`
|
|
668
|
-
- `remove(name, callback?)`
|
|
669
|
-
- `start(callback?)`
|
|
670
|
-
- `stop(callback?)`
|
|
671
|
-
- `get_resources_by_type(type)`
|
|
672
|
-
|
|
673
|
-
**Properties:**
|
|
674
|
-
- `summary`: Aggregated state summary grouped by resource type.
|
|
675
|
-
|
|
676
|
-
**Forwarded Events:**
|
|
677
|
-
- `resource_state_change`
|
|
678
|
-
- `crashed`
|
|
679
|
-
- `unhealthy`
|
|
680
|
-
- `unreachable`
|
|
681
|
-
- `recovered`
|
|
682
|
-
|
|
683
|
-
### File_System_Resource
|
|
716
|
+
```javascript
|
|
717
|
+
serve(request: IncomingMessage, response: ServerResponse): Promise<void>
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
### HTTP_SSE_Publisher
|
|
721
|
+
|
|
722
|
+
General-purpose SSE publisher for explicit event fan-out.
|
|
723
|
+
|
|
724
|
+
**Extends:** `HTTP_Publisher`
|
|
725
|
+
|
|
726
|
+
**Constructor:**
|
|
727
|
+
```javascript
|
|
728
|
+
new HTTP_SSE_Publisher(spec?: {
|
|
729
|
+
name?: string,
|
|
730
|
+
keepaliveIntervalMs?: number,
|
|
731
|
+
maxClients?: number,
|
|
732
|
+
eventHistorySize?: number
|
|
733
|
+
})
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
**Methods:**
|
|
737
|
+
- `handle_http(req, res)`
|
|
738
|
+
- `broadcast(event_name, data_value)`
|
|
739
|
+
- `send(client_id, event_name, data_value)`
|
|
740
|
+
- `stop(callback?)`
|
|
741
|
+
|
|
742
|
+
**Properties:**
|
|
743
|
+
- `client_count` (number)
|
|
744
|
+
|
|
745
|
+
## Resource Classes
|
|
746
|
+
|
|
747
|
+
### Process_Resource
|
|
748
|
+
|
|
749
|
+
Represents a local process as a resource with a unified lifecycle API.
|
|
750
|
+
|
|
751
|
+
**Extends:** `Resource`
|
|
752
|
+
|
|
753
|
+
**Constructor:**
|
|
754
|
+
```javascript
|
|
755
|
+
new Process_Resource(spec?: {
|
|
756
|
+
name?: string,
|
|
757
|
+
command?: string,
|
|
758
|
+
args?: string[],
|
|
759
|
+
cwd?: string,
|
|
760
|
+
env?: object,
|
|
761
|
+
autoRestart?: boolean,
|
|
762
|
+
maxRestarts?: number,
|
|
763
|
+
processManager?: 'direct' | {
|
|
764
|
+
type: 'direct' | 'pm2',
|
|
765
|
+
pm2Path?: string,
|
|
766
|
+
ecosystem?: string
|
|
767
|
+
},
|
|
768
|
+
healthCheck?: {
|
|
769
|
+
type: 'http' | 'tcp' | 'custom',
|
|
770
|
+
url?: string,
|
|
771
|
+
host?: string,
|
|
772
|
+
port?: number,
|
|
773
|
+
fn?: Function,
|
|
774
|
+
intervalMs?: number,
|
|
775
|
+
timeoutMs?: number,
|
|
776
|
+
failuresBeforeUnhealthy?: number
|
|
777
|
+
}
|
|
778
|
+
})
|
|
779
|
+
```
|
|
780
|
+
|
|
781
|
+
**Core Methods:**
|
|
782
|
+
- `start(callback?)`
|
|
783
|
+
- `stop(callback?)`
|
|
784
|
+
- `restart(callback?)`
|
|
785
|
+
- `get_abstract()`
|
|
786
|
+
|
|
787
|
+
**Status:**
|
|
788
|
+
```javascript
|
|
789
|
+
{
|
|
790
|
+
state: 'stopped' | 'starting' | 'running' | 'stopping' | 'restarting' | 'crashed',
|
|
791
|
+
pid: number | null,
|
|
792
|
+
uptime: number,
|
|
793
|
+
restartCount: number,
|
|
794
|
+
lastHealthCheck: object | null,
|
|
795
|
+
memoryUsage: object | null,
|
|
796
|
+
processManager: { type: 'direct' | 'pm2' }
|
|
797
|
+
}
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
**Events:**
|
|
801
|
+
- `state_change`
|
|
802
|
+
- `stdout`
|
|
803
|
+
- `stderr`
|
|
804
|
+
- `exit`
|
|
805
|
+
- `health_check`
|
|
806
|
+
- `unhealthy`
|
|
807
|
+
- `crashed`
|
|
808
|
+
|
|
809
|
+
### Remote_Process_Resource
|
|
810
|
+
|
|
811
|
+
Represents a remote HTTP-controlled process using the same lifecycle-oriented API style as `Process_Resource`.
|
|
812
|
+
|
|
813
|
+
**Extends:** `Resource`
|
|
814
|
+
|
|
815
|
+
**Constructor:**
|
|
816
|
+
```javascript
|
|
817
|
+
new Remote_Process_Resource(spec?: {
|
|
818
|
+
name?: string,
|
|
819
|
+
host: string,
|
|
820
|
+
port: number,
|
|
821
|
+
protocol?: 'http' | 'https',
|
|
822
|
+
pollIntervalMs?: number,
|
|
823
|
+
httpTimeoutMs?: number,
|
|
824
|
+
historySize?: number,
|
|
825
|
+
unreachableFailuresBeforeEvent?: number,
|
|
826
|
+
endpoints?: {
|
|
827
|
+
status?: string,
|
|
828
|
+
start?: string,
|
|
829
|
+
stop?: string,
|
|
830
|
+
health?: string
|
|
831
|
+
}
|
|
832
|
+
})
|
|
833
|
+
```
|
|
834
|
+
|
|
835
|
+
**Core Methods:**
|
|
836
|
+
- `start(callback?)`
|
|
837
|
+
- `stop(callback?)`
|
|
838
|
+
- `restart(callback?)`
|
|
839
|
+
- `get_abstract()`
|
|
840
|
+
|
|
841
|
+
**Status:** Includes `state`, `pid`, `uptime`, `restartCount`, `lastHealthCheck`, `memoryUsage`, and `processManager: { type: 'remote' }`.
|
|
842
|
+
|
|
843
|
+
**Events:**
|
|
844
|
+
- `state_change`
|
|
845
|
+
- `unreachable`
|
|
846
|
+
- `recovered`
|
|
847
|
+
|
|
848
|
+
### Server_Resource_Pool
|
|
849
|
+
|
|
850
|
+
Server-specific resource pool with lifecycle orchestration and event forwarding.
|
|
851
|
+
|
|
852
|
+
**Extends:** `Resource_Pool`
|
|
853
|
+
|
|
854
|
+
**Methods:**
|
|
855
|
+
- `add(resource)`
|
|
856
|
+
- `remove(name, callback?)`
|
|
857
|
+
- `start(callback?)`
|
|
858
|
+
- `stop(callback?)`
|
|
859
|
+
- `get_resources_by_type(type)`
|
|
860
|
+
|
|
861
|
+
**Properties:**
|
|
862
|
+
- `summary`: Aggregated state summary grouped by resource type.
|
|
863
|
+
|
|
864
|
+
**Forwarded Events:**
|
|
865
|
+
- `resource_state_change`
|
|
866
|
+
- `crashed`
|
|
867
|
+
- `unhealthy`
|
|
868
|
+
- `unreachable`
|
|
869
|
+
- `recovered`
|
|
870
|
+
|
|
871
|
+
### File_System_Resource
|
|
684
872
|
|
|
685
873
|
Provides access to local file system.
|
|
686
874
|
|
|
@@ -912,12 +1100,16 @@ ensure_route_leading_slash(route: string): string
|
|
|
912
1100
|
### ServerOptions
|
|
913
1101
|
|
|
914
1102
|
```typescript
|
|
915
|
-
interface ServerOptions {
|
|
916
|
-
ctrl?: Function;
|
|
917
|
-
Ctrl?: Function;
|
|
918
|
-
src_path_client_js?: string;
|
|
1103
|
+
interface ServerOptions {
|
|
1104
|
+
ctrl?: Function;
|
|
1105
|
+
Ctrl?: Function;
|
|
1106
|
+
src_path_client_js?: string;
|
|
919
1107
|
port?: number;
|
|
920
1108
|
host?: string;
|
|
1109
|
+
on_port_conflict?: 'error' | 'auto-loopback';
|
|
1110
|
+
start?: {
|
|
1111
|
+
on_port_conflict?: 'error' | 'auto-loopback';
|
|
1112
|
+
};
|
|
921
1113
|
debug?: boolean;
|
|
922
1114
|
name?: string;
|
|
923
1115
|
root?: string;
|
|
@@ -928,60 +1120,66 @@ interface ServerOptions {
|
|
|
928
1120
|
api?: Record<string, Function>;
|
|
929
1121
|
static?: Record<string, string>;
|
|
930
1122
|
|
|
931
|
-
//
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
1123
|
+
// Middleware & compression
|
|
1124
|
+
middleware?: Function | Function[]; // (req, res, next) middleware functions
|
|
1125
|
+
compression?: boolean | { // Enable built-in compression middleware
|
|
1126
|
+
threshold?: number; // Min body size to compress (default 1024)
|
|
1127
|
+
level?: number; // zlib level (default Z_DEFAULT_COMPRESSION)
|
|
1128
|
+
};
|
|
1129
|
+
|
|
1130
|
+
// Advanced options
|
|
1131
|
+
cors?: CorsConfig;
|
|
1132
|
+
https?: HttpsConfig;
|
|
1133
|
+
publishers?: Record<string, Publisher>;
|
|
1134
|
+
resources?: ResourceEntries;
|
|
1135
|
+
events?: boolean | EventsOptions;
|
|
1136
|
+
bundler?: BundlerConfig;
|
|
1137
|
+
}
|
|
1138
|
+
```
|
|
1139
|
+
|
|
1140
|
+
```typescript
|
|
1141
|
+
type ResourceEntries = Record<string, ResourceEntry> | ResourceEntry[];
|
|
1142
|
+
|
|
1143
|
+
type ResourceEntry =
|
|
1144
|
+
| Resource
|
|
1145
|
+
| {
|
|
1146
|
+
type?: 'process' | 'local';
|
|
1147
|
+
command?: string;
|
|
1148
|
+
args?: string[];
|
|
1149
|
+
processManager?: 'direct' | {
|
|
1150
|
+
type?: 'direct' | 'pm2';
|
|
1151
|
+
pm2Path?: string;
|
|
1152
|
+
ecosystem?: string;
|
|
1153
|
+
};
|
|
1154
|
+
[key: string]: any;
|
|
1155
|
+
}
|
|
1156
|
+
| {
|
|
1157
|
+
type?: 'remote' | 'http';
|
|
1158
|
+
host?: string;
|
|
1159
|
+
port?: number;
|
|
1160
|
+
protocol?: 'http' | 'https';
|
|
1161
|
+
endpoints?: Record<string, string>;
|
|
1162
|
+
[key: string]: any;
|
|
1163
|
+
}
|
|
1164
|
+
| {
|
|
1165
|
+
type?: 'resource' | 'in_process' | 'in-process';
|
|
1166
|
+
instance?: Resource;
|
|
1167
|
+
resource?: Resource;
|
|
1168
|
+
class?: new (spec?: any) => Resource;
|
|
1169
|
+
Ctor?: new (spec?: any) => Resource;
|
|
1170
|
+
constructor_fn?: new (spec?: any) => Resource;
|
|
1171
|
+
spec?: Record<string, any>;
|
|
1172
|
+
[key: string]: any;
|
|
1173
|
+
};
|
|
1174
|
+
|
|
1175
|
+
interface EventsOptions {
|
|
1176
|
+
route?: string;
|
|
1177
|
+
name?: string;
|
|
1178
|
+
keepaliveIntervalMs?: number;
|
|
1179
|
+
maxClients?: number;
|
|
1180
|
+
eventHistorySize?: number;
|
|
1181
|
+
}
|
|
1182
|
+
```
|
|
985
1183
|
|
|
986
1184
|
### PageConfig
|
|
987
1185
|
|
|
@@ -1287,4 +1485,4 @@ const server = await Server.serve({
|
|
|
1287
1485
|
|
|
1288
1486
|
---
|
|
1289
1487
|
|
|
1290
|
-
This API reference provides comprehensive technical documentation for JSGUI3 Server internals. For practical usage examples and tutorials, refer to the user-facing documentation.
|
|
1488
|
+
This API reference provides comprehensive technical documentation for JSGUI3 Server internals. For practical usage examples and tutorials, refer to the user-facing documentation.
|