Skip to content

Commit 3bff8d8

Browse files
committed
0.0.151 - Add middleware support with built-in compression and documentation
1 parent 55d77fb commit 3bff8d8

File tree

14 files changed

+761
-34
lines changed

14 files changed

+761
-34
lines changed

.github/instructions/copilot.instructions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,5 +176,6 @@ model.count++; // Triggers change event
176176
| Comprehensive API | `docs/comprehensive-documentation.md` |
177177
| Control development | `docs/controls-development.md` |
178178
| Publisher system | `docs/publishers-guide.md` |
179+
| Middleware & compression | `docs/middleware-guide.md` |
179180
| Troubleshooting | `docs/troubleshooting.md` |
180181
| **Broken stuff** | `docs/agent-development-guide.md` |

AGENTS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
- **[docs/controls-development.md](docs/controls-development.md)** - Guide for developing custom JSGUI3 controls
2020
- **[docs/publishers-guide.md](docs/publishers-guide.md)** - Guide for publishers and content serving
2121
- **[docs/resources-guide.md](docs/resources-guide.md)** - Guide for resources and data abstraction
22+
- **[docs/middleware-guide.md](docs/middleware-guide.md)** - Middleware pipeline and built-in compression middleware
2223

2324
### Specialized Documentation
2425
- **[docs/GUIDE_TO_AGENTIC_WORKFLOWS_BY_GROK.md](docs/GUIDE_TO_AGENTIC_WORKFLOWS_BY_GROK.md)** - Comprehensive guide to agentic workflows and autonomous task execution
@@ -61,6 +62,7 @@
6162
- **Custom control development**`docs/controls-development.md`
6263
- **Publisher system**`docs/publishers-guide.md`
6364
- **Resource management**`docs/resources-guide.md`
65+
- **Middleware and compression**`docs/middleware-guide.md`
6466
- **Admin UI extensions**`docs/admin-extension-guide.md`
6567

6668
### Agent Development

README.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,61 @@ jsgui.Admin_User_Store
298298

299299
See [Admin Extension Guide](docs/admin-extension-guide.md) for detailed API reference.
300300

301+
## Middleware
302+
303+
jsgui3-server includes an Express-style `server.use()` middleware pipeline. Middleware runs before every request reaches the router.
304+
305+
### Built-in Compression
306+
307+
Enable gzip/deflate/brotli compression for JSON, HTML, CSS, and JS responses:
308+
309+
```javascript
310+
const { compression } = require('jsgui3-server/middleware');
311+
312+
const server = new Server({ Ctrl: MyControl, src_path_client_js: __dirname + '/client.js' });
313+
server.use(compression());
314+
server.on('ready', () => server.start(8080));
315+
```
316+
317+
Or via `Server.serve()`:
318+
319+
```javascript
320+
Server.serve({
321+
Ctrl: MyControl,
322+
compression: true, // enable with defaults
323+
port: 8080
324+
});
325+
326+
// With options:
327+
Server.serve({
328+
Ctrl: MyControl,
329+
compression: { threshold: 512 },
330+
port: 8080
331+
});
332+
```
333+
334+
### Custom Middleware
335+
336+
```javascript
337+
// Request logger
338+
server.use((req, res, next) => {
339+
console.log(`${req.method} ${req.url}`);
340+
next();
341+
});
342+
343+
// Multiple middleware via Server.serve()
344+
Server.serve({
345+
Ctrl: MyControl,
346+
middleware: [
347+
(req, res, next) => { console.log(req.url); next(); },
348+
compression({ threshold: 512 })
349+
],
350+
port: 8080
351+
});
352+
```
353+
354+
See [Middleware Guide](docs/middleware-guide.md) for the full API reference and response-wrapping patterns.
355+
301356
## Architecture Overview
302357

303358
The server operates as a bridge between server-side JavaScript applications and browser clients, offering:

docs/api-reference.md

Lines changed: 85 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,17 +151,91 @@ server.close(callback?: (err?: Error | null) => void): void
151151
- Stops `sse_publisher` when present
152152
- Closes all HTTP listeners
153153

154-
### server.use(middleware)
154+
### server.use(fn)
155155

156-
Adds middleware to the server.
156+
Register middleware to run before every request is routed. Middleware is executed
157+
in registration order. The chain runs to completion before the router processes
158+
the request.
157159

158160
**Signature:**
159161
```javascript
160-
server.use(middleware: Function): void
162+
server.use(fn: Function): Server // returns `this` for chaining
161163
```
162164

163165
**Parameters:**
164-
- `middleware` (Function): Express-style middleware function
166+
- `fn` (Function): Middleware function with signature `(req, res, next) => void`
167+
- `req` — Node.js `http.IncomingMessage`
168+
- `res` — Node.js `http.ServerResponse`
169+
- `next` — Call `next()` to continue to the next middleware / router.
170+
Call `next(err)` to skip remaining middleware and trigger the error handler
171+
(500 response).
172+
173+
**Returns:** The server instance (for chaining).
174+
175+
**Throws:** `Error` if `fn` is not a function.
176+
177+
**Example:**
178+
```javascript
179+
const { compression } = require('jsgui3-server/middleware');
180+
181+
server
182+
.use((req, res, next) => {
183+
console.log(`${req.method} ${req.url}`);
184+
next();
185+
})
186+
.use(compression());
187+
```
188+
189+
**Execution order:**
190+
```
191+
HTTP Request → middleware[0] → middleware[1] → … → router
192+
```
193+
194+
If no middleware is registered, the router is called directly with zero overhead.
195+
196+
**See also:** [Middleware Guide](middleware-guide.md) for response-wrapping
197+
patterns, custom middleware examples, and the built-in compression reference.
198+
199+
---
200+
201+
### Built-in Middleware
202+
203+
#### `compression([options])`
204+
205+
Response-compression middleware. Transparently compresses response bodies
206+
(gzip / deflate / brotli) when the client supports it and the content type
207+
is compressible.
208+
209+
```javascript
210+
const { compression } = require('jsgui3-server/middleware');
211+
server.use(compression()); // defaults
212+
server.use(compression({ threshold: 512 })); // lower threshold
213+
```
214+
215+
**Options:**
216+
217+
| Option | Type | Default | Description |
218+
|-----------|--------|---------------------------|-------------------------------------------|
219+
| `threshold` | number | `1024` | Minimum body size in bytes to compress |
220+
| `level` | number | `Z_DEFAULT_COMPRESSION` | zlib compression level (1–9, or -1) |
221+
222+
**Encoding priority:** gzip → deflate → brotli
223+
224+
**Compressible types:** `application/json`, `text/html`, `text/plain`,
225+
`text/css`, `text/xml`, `text/csv`, `text/javascript`,
226+
`application/javascript`, `application/xml`, `application/xhtml+xml`,
227+
`application/manifest+json`, `image/svg+xml`.
228+
229+
**Not compressed:** bodies below threshold, binary content types, responses
230+
with an existing `Content-Encoding`, and streaming responses (`res.write()`
231+
before `res.end()` — e.g. SSE).
232+
233+
**Access paths:**
234+
```javascript
235+
require('jsgui3-server/middleware').compression // direct
236+
require('jsgui3-server').middleware.compression // via module
237+
Server.middleware.compression // via class
238+
```
165239

166240
## Port Utilities
167241

@@ -928,10 +1002,16 @@ interface ServerOptions {
9281002
api?: Record<string, Function>;
9291003
static?: Record<string, string>;
9301004

1005+
// Middleware & compression
1006+
middleware?: Function | Function[]; // (req, res, next) middleware functions
1007+
compression?: boolean | { // Enable built-in compression middleware
1008+
threshold?: number; // Min body size to compress (default 1024)
1009+
level?: number; // zlib level (default Z_DEFAULT_COMPRESSION)
1010+
};
1011+
9311012
// Advanced options
9321013
cors?: CorsConfig;
9331014
https?: HttpsConfig;
934-
middleware?: Function[];
9351015
publishers?: Record<string, Publisher>;
9361016
resources?: ResourceEntries;
9371017
events?: boolean | EventsOptions;

docs/comprehensive-documentation.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,7 @@ const server = Server.serve({
11101110
debug: false, // Disable for production
11111111
// Additional production settings
11121112
max_age: 86400, // Cache static assets for 24 hours
1113-
compress: true // Enable gzip compression
1113+
compression: true // Enable gzip/deflate/brotli compression
11141114
});
11151115
```
11161116

@@ -1300,8 +1300,8 @@ Server.serve({
13001300
src_path_client_js: require.resolve('./client.js'),
13011301
// Cache static assets
13021302
max_age: 86400, // 24 hours
1303-
// Enable compression
1304-
compress: true,
1303+
// Enable compression (gzip/deflate/brotli via built-in middleware)
1304+
compression: true,
13051305
// Optimize bundling
13061306
debug: false
13071307
});

docs/configuration-reference.md

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -486,16 +486,16 @@ Server.serve({
486486
});
487487
```
488488

489-
### Middleware
489+
### `middleware`
490+
- **Type:** `Function | Function[]`
491+
- **Description:** One or more Express-style middleware functions `(req, res, next)` to run before every request reaches the router. Middleware is executed in array order.
490492

491493
```javascript
492-
const express = require('express');
493-
const compression = require('compression');
494+
const { compression } = require('jsgui3-server/middleware');
494495

495496
Server.serve({
496497
middleware: [
497-
compression(),
498-
express.json({ limit: '10mb' }),
498+
compression({ threshold: 512 }),
499499
(req, res, next) => {
500500
console.log(`${req.method} ${req.url}`);
501501
next();
@@ -504,6 +504,29 @@ Server.serve({
504504
});
505505
```
506506

507+
### `compression`
508+
- **Type:** `boolean | Object`
509+
- **Description:** Convenience shorthand that enables the built-in response-compression middleware. Pass `true` for defaults or an options object.
510+
- **Default:** Disabled (no compression)
511+
512+
| Sub-option | Type | Default | Description |
513+
|------------|--------|---------------------------|--------------------------------------------|
514+
| `threshold` | number | `1024` | Minimum body size (bytes) to compress |
515+
| `level` | number | `Z_DEFAULT_COMPRESSION` | zlib compression level (1–9, or -1 for default) |
516+
517+
```javascript
518+
// Enable with defaults (1024 byte threshold, gzip preferred)
519+
Server.serve({ compression: true });
520+
521+
// Enable with custom options
522+
Server.serve({ compression: { threshold: 256, level: 6 } });
523+
```
524+
525+
> **Note:** `compression` and `middleware` can be used together. The `middleware` array runs first (in order), then the compression middleware is appended.
526+
527+
See [Middleware Guide](middleware-guide.md) for the full API, response-wrapping patterns, and custom middleware examples.
528+
```
529+
507530
## Configuration Validation
508531
509532
### Type Checking

0 commit comments

Comments
 (0)