feat(server): use UtilityWebsiteServer for dev server, add domain option, update docs, and bump dependencies

This commit is contained in:
2026-03-10 15:54:55 +00:00
parent b62e380750
commit 07cdee6bff
9 changed files with 1012 additions and 569 deletions

View File

@@ -1,5 +1,14 @@
# Changelog # Changelog
## 2026-03-10 - 3.3.0 - feat(server)
use UtilityWebsiteServer for dev server, add domain option, update docs, and bump dependencies
- Replace TypedServer with UtilityWebsiteServer in TsWatch (start/stop/reload adapted)
- Add server.domain config option and update interfaces
- Update readme to document UtilityWebsiteServer features (PWA, brotli+gzip, service worker, live reload via WebSocket) and add bundle config hints (outputMode, bundler, production)
- Bump dependencies and devDependencies (notable: @api.global/typedserver ^8.4.2, @git.zone/tsbundle ^2.9.1, @push.rocks/* updates)
- Remove unused taskbuffer export from tswatch.plugins.ts
## 2026-03-03 - 3.2.1 - fix(watcher) ## 2026-03-03 - 3.2.1 - fix(watcher)
ensure child processes are killed and awaited during shutdown; improve cleanup handlers; bump smartshell dependency to ^3.3.2 ensure child processes are killed and awaited during shutdown; improve cleanup handlers; bump smartshell dependency to ^3.3.2

View File

@@ -18,27 +18,26 @@
"buildDocs": "tsdoc" "buildDocs": "tsdoc"
}, },
"devDependencies": { "devDependencies": {
"@git.zone/tsbuild": "^4.1.2", "@git.zone/tsbuild": "^4.3.0",
"@git.zone/tstest": "^3.1.8", "@git.zone/tstest": "^3.3.2",
"@types/node": "^25.2.1" "@types/node": "^25.4.0"
}, },
"dependencies": { "dependencies": {
"@api.global/typedserver": "^8.3.0", "@api.global/typedserver": "^8.4.2",
"@git.zone/tsbundle": "^2.9.0", "@git.zone/tsbundle": "^2.9.1",
"@git.zone/tsrun": "^2.0.1", "@git.zone/tsrun": "^2.0.1",
"@push.rocks/early": "^4.0.4", "@push.rocks/early": "^4.0.4",
"@push.rocks/lik": "^6.2.2", "@push.rocks/lik": "^6.3.1",
"@push.rocks/npmextra": "^5.3.3", "@push.rocks/npmextra": "^5.3.3",
"@push.rocks/smartcli": "^4.0.20", "@push.rocks/smartcli": "^4.0.20",
"@push.rocks/smartdelay": "^3.0.5", "@push.rocks/smartdelay": "^3.0.5",
"@push.rocks/smartexit": "^2.0.2", "@push.rocks/smartexit": "^2.0.3",
"@push.rocks/smartfs": "^1.3.1", "@push.rocks/smartfs": "^1.5.0",
"@push.rocks/smartinteract": "^2.0.16", "@push.rocks/smartinteract": "^2.0.16",
"@push.rocks/smartlog": "^3.1.10", "@push.rocks/smartlog": "^3.2.1",
"@push.rocks/smartlog-destination-local": "^9.0.2", "@push.rocks/smartlog-destination-local": "^9.0.2",
"@push.rocks/smartshell": "^3.3.5", "@push.rocks/smartshell": "^3.3.7",
"@push.rocks/smartwatch": "^6.3.0", "@push.rocks/smartwatch": "^6.3.0"
"@push.rocks/taskbuffer": "^4.2.0"
}, },
"files": [ "files": [
"ts/**/*", "ts/**/*",

1490
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -66,7 +66,7 @@ tswatch is now a config-driven TypeScript file watcher. Configuration is read fr
- Uses `@push.rocks/npmextra` for reading npmextra.json config - Uses `@push.rocks/npmextra` for reading npmextra.json config
- Uses `@push.rocks/smartinteract` for the init wizard - Uses `@push.rocks/smartinteract` for the init wizard
- Uses `@git.zone/tsbundle` for bundling with esbuild - Uses `@git.zone/tsbundle` for bundling with esbuild
- Uses `@api.global/typedserver` for development server - Uses `@api.global/typedserver` `UtilityWebsiteServer` for development server (wraps TypedServer with service worker, PWA manifest, and live reload)
### Watcher Features ### Watcher Features
@@ -77,12 +77,16 @@ tswatch is now a config-driven TypeScript file watcher. Configuration is read fr
### Server Features ### Server Features
- Uses `UtilityWebsiteServer` from `@api.global/typedserver` (not raw `TypedServer`)
- Port configurable (default: 3002) - Port configurable (default: 3002)
- CORS enabled - CORS enabled
- Gzip compression - Compression (brotli + gzip)
- Live reload injection (configurable) - Live reload via WebSocket (service worker + devtools injection)
- SPA fallback support - SPA fallback support
- No-cache headers (prevents browser caching during development) - No-cache headers (prevents browser caching during development)
- PWA manifest auto-generated
- Service worker version info handler
- Domain configurable (default: 'localhost')
## Project Structure ## Project Structure

View File

@@ -153,6 +153,7 @@ tswatch uses `npmextra.json` for configuration. Add your config under the `@git.
| `port` | `number` | `3002` | Server port | | `port` | `number` | `3002` | Server port |
| `serveDir` | `string` | `./dist_watch/` | Directory to serve | | `serveDir` | `string` | `./dist_watch/` | Directory to serve |
| `liveReload` | `boolean` | `true` | Inject live reload script | | `liveReload` | `boolean` | `true` | Inject live reload script |
| `domain` | `string` | `localhost` | Domain name for the dev server |
#### `IBundleConfig` #### `IBundleConfig`
@@ -163,6 +164,9 @@ tswatch uses `npmextra.json` for configuration. Add your config under the `@git.
| `to` | `string` | *required* | Output file | | `to` | `string` | *required* | Output file |
| `watchPatterns` | `string[]` | - | Additional patterns to watch | | `watchPatterns` | `string[]` | - | Additional patterns to watch |
| `triggerReload` | `boolean` | `true` | Trigger server reload after bundling | | `triggerReload` | `boolean` | `true` | Trigger server reload after bundling |
| `outputMode` | `'bundle' \| 'base64ts'` | `'bundle'` | Output mode for the bundle |
| `bundler` | `'esbuild' \| 'rolldown' \| 'rspack'` | `'esbuild'` | Bundler to use |
| `production` | `boolean` | `false` | Produce a production build |
## 🛠️ CLI Commands ## 🛠️ CLI Commands
@@ -368,19 +372,22 @@ Config:
## 🌐 Development Server ## 🌐 Development Server
The built-in development server (enabled in `element` and `website` presets) features: The built-in development server (powered by `@api.global/typedserver`'s `UtilityWebsiteServer`) is enabled in `element` and `website` presets:
- **Live Reload** - Automatically refreshes browser on changes - 🔄 **Live Reload** - WebSocket-based instant browser refresh on changes (via service worker + devtools injection)
- **No Caching** - Prevents browser caching during development (sends `Cache-Control: no-store, no-cache` headers) - 🚫 **No Caching** - Prevents browser caching during development (`Cache-Control: no-store, no-cache` headers)
- **CORS** - Cross-origin requests enabled - 🌍 **CORS** - Cross-origin requests enabled
- **Compression** - Gzip compression for faster loading - 🗜️ **Compression** - Brotli + gzip compression for faster loading
- **SPA Fallback** - Single-page application routing support - 📱 **SPA Fallback** - Single-page application routing support
- **Security Headers** - Cross-origin isolation headers - 🔒 **Security Headers** - Cross-origin isolation (`COOP`, `COEP`)
- 📦 **PWA Manifest** - Auto-generated Progressive Web App manifest
-**Service Worker** - Built-in service worker version info for cache busting
Default configuration: Default configuration:
- **Port**: 3002 - **Port**: 3002
- **Serve Directory**: `./dist_watch/` - **Serve Directory**: `./dist_watch/`
- **Live Reload**: Enabled - **Live Reload**: Enabled
- **Domain**: `localhost`
## 🔧 Configuration Tips ## 🔧 Configuration Tips

View File

@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@git.zone/tswatch', name: '@git.zone/tswatch',
version: '3.2.1', version: '3.3.0',
description: 'A development tool for automatically watching and re-compiling TypeScript projects upon detecting file changes, enhancing developer workflows.' description: 'A development tool for automatically watching and re-compiling TypeScript projects upon detecting file changes, enhancing developer workflows.'
} }

View File

@@ -28,6 +28,8 @@ export interface IServerConfig {
serveDir?: string; serveDir?: string;
/** Whether to inject live reload script (default: true) */ /** Whether to inject live reload script (default: true) */
liveReload?: boolean; liveReload?: boolean;
/** Domain name for the dev server (default: 'localhost') */
domain?: string;
} }
/** /**

View File

@@ -15,7 +15,7 @@ import { logger } from './tswatch.logging.js';
export class TsWatch { export class TsWatch {
public config: interfaces.ITswatchConfig; public config: interfaces.ITswatchConfig;
public watcherMap = new plugins.lik.ObjectMap<Watcher>(); public watcherMap = new plugins.lik.ObjectMap<Watcher>();
public typedserver: plugins.typedserver.TypedServer | null = null; public utilityWebsiteServer: plugins.typedserver.utilityservers.UtilityWebsiteServer | null = null;
private tsbundle = new plugins.tsbundle.TsBundle(); private tsbundle = new plugins.tsbundle.TsBundle();
private customBundleHandler = new plugins.tsbundle.CustomBundleHandler(); private customBundleHandler = new plugins.tsbundle.CustomBundleHandler();
@@ -75,8 +75,8 @@ export class TsWatch {
}); });
// Start server after watchers are ready // Start server after watchers are ready
if (this.typedserver) { if (this.utilityWebsiteServer) {
await this.typedserver.start(); await this.utilityWebsiteServer.start(this.config.server?.port || 3002);
logger.log('ok', `Dev server started on port ${this.config.server?.port || 3002}`); logger.log('ok', `Dev server started on port ${this.config.server?.port || 3002}`);
} }
} }
@@ -91,14 +91,14 @@ export class TsWatch {
logger.log('info', `Setting up dev server on port ${port}, serving ${serveDir}`); logger.log('info', `Setting up dev server on port ${port}, serving ${serveDir}`);
this.typedserver = new plugins.typedserver.TypedServer({ this.utilityWebsiteServer = new plugins.typedserver.utilityservers.UtilityWebsiteServer({
cors: true, domain: serverConfig.domain || 'localhost',
injectReload: serverConfig.liveReload !== false,
serveDir: plugins.path.join(paths.cwd, serveDir), serveDir: plugins.path.join(paths.cwd, serveDir),
port: port, port: port,
compression: true, cors: true,
spaFallback: true, spaFallback: true,
noCache: true, noCache: true,
injectReload: serverConfig.liveReload !== false,
securityHeaders: { securityHeaders: {
crossOriginOpenerPolicy: 'same-origin', crossOriginOpenerPolicy: 'same-origin',
crossOriginEmbedderPolicy: 'require-corp', crossOriginEmbedderPolicy: 'require-corp',
@@ -159,8 +159,8 @@ export class TsWatch {
logger.log('ok', `[${name}] bundle complete`); logger.log('ok', `[${name}] bundle complete`);
// Trigger reload if configured and server is running // Trigger reload if configured and server is running
if (bundleConfig.triggerReload !== false && this.typedserver) { if (bundleConfig.triggerReload !== false && this.utilityWebsiteServer?.typedserver) {
await this.typedserver.reload(); await this.utilityWebsiteServer.typedserver.reload();
} }
}; };
@@ -211,8 +211,8 @@ export class TsWatch {
* stops the execution of any active Watchers * stops the execution of any active Watchers
*/ */
public async stop() { public async stop() {
if (this.typedserver) { if (this.utilityWebsiteServer) {
await this.typedserver.stop(); await this.utilityWebsiteServer.stop();
} }
await this.watcherMap.forEach(async (watcher) => { await this.watcherMap.forEach(async (watcher) => {
await watcher.stop(); await watcher.stop();

View File

@@ -23,7 +23,6 @@ import * as smartlog from '@push.rocks/smartlog';
import * as smartlogDestinationLocal from '@push.rocks/smartlog-destination-local'; import * as smartlogDestinationLocal from '@push.rocks/smartlog-destination-local';
import * as smartshell from '@push.rocks/smartshell'; import * as smartshell from '@push.rocks/smartshell';
import * as smartwatch from '@push.rocks/smartwatch'; import * as smartwatch from '@push.rocks/smartwatch';
import * as taskbuffer from '@push.rocks/taskbuffer';
export { export {
lik, lik,
@@ -37,5 +36,4 @@ export {
smartlogDestinationLocal, smartlogDestinationLocal,
smartshell, smartshell,
smartwatch, smartwatch,
taskbuffer,
}; };