fix(readme): Update README to reflect new features and updated examples (SPA/PWA/Edge/ServiceWorker) and clarify API usage

This commit is contained in:
2025-12-05 10:00:40 +00:00
parent 790b468188
commit 76b5cb5142
3 changed files with 102 additions and 104 deletions

View File

@@ -1,5 +1,14 @@
# Changelog
## 2025-12-05 - 7.8.18 - fix(readme)
Update README to reflect new features and updated examples (SPA/PWA/Edge/ServiceWorker) and clarify API usage
- Rewrite project introduction and features list to highlight Service Worker, Edge Workers, SPA support, and PWA readiness
- Replace and expand example sections: Basic Server, Full Configuration, TypedRequest handlers, WebSocket usage, Edge Worker entrypoint, and Service Worker client usage
- Update configuration reference: remove legacy compression flags, add spaFallback, defaultAnswer, feedMetadata, and blockWaybackMachine options
- Document package exports and add examples for utility servers (WebsiteServer, ServiceServer)
- Clarify TypedRequest/TypedSocket usage by showing server.typedrouter and service worker client initializer (getServiceworkerClient)
## 2025-12-04 - 7.8.11 - fix(web_inject)
Improve logging in web injection (TypedRequest) and update dees-comms dependency

195
readme.md
View File

@@ -1,6 +1,6 @@
# @api.global/typedserver
A powerful TypeScript-first web server framework featuring static file serving, live reload, compression, and seamless type-safe API integration. Part of the `@api.global` ecosystem, it provides a modern foundation for building full-stack TypeScript applications with first-class support for typed HTTP requests and WebSocket communication.
A TypeScript-first web server framework for building modern full-stack applications. Features static file serving, live reload, type-safe API integration, service worker support, and edge computing capabilities. Part of the `@api.global` ecosystem.
## Issue Reporting and Security
@@ -8,15 +8,14 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
## ✨ Features
- 🔒 **Type-Safe API Ecosystem** - Full TypeScript support with `@api.global/typedrequest` and `@api.global/typedsocket`
- 🔒 **Type-Safe API** - Full TypeScript support with `@api.global/typedrequest` and `@api.global/typedsocket`
-**Live Reload** - Automatic browser refresh on file changes during development
- 🗜 **Compression** - Built-in support for gzip, deflate, and brotli compression
- 🌐 **CORS Management** - Flexible cross-origin resource sharing configuration
- 🔧 **Service Worker Integration** - Advanced caching and offline capabilities
- **Edge Worker Support** - Cloudflare Workers compatible edge computing
- 📡 **WebSocket Support** - Real-time bidirectional communication via TypedSocket
- 🗺️ **Sitemap & Feeds** - Automatic sitemap and RSS feed generation
- 🤖 **Robots.txt** - Built-in robots.txt handling
- 🛠 **Service Worker** - Advanced caching, offline support, and background sync
- ☁️ **Edge Workers** - Cloudflare Workers compatible edge computing with domain routing
- 📡 **WebSocket** - Real-time bidirectional communication via TypedSocket
- 🗺 **SEO Tools** - Built-in sitemap, RSS feed, and robots.txt generation
- 🎯 **SPA Support** - Single-page application fallback routing
- 📱 **PWA Ready** - Web App Manifest generation for progressive web apps
## 📦 Installation
@@ -30,7 +29,7 @@ npm install @api.global/typedserver
## 🚀 Quick Start
### Basic Static File Server
### Basic Server
```typescript
import { TypedServer } from '@api.global/typedserver';
@@ -43,10 +42,10 @@ const server = new TypedServer({
});
await server.start();
console.log('Server running on port 3000');
console.log('Server running!');
```
### Server with All Options
### Full Configuration
```typescript
import { TypedServer } from '@api.global/typedserver';
@@ -55,15 +54,23 @@ const server = new TypedServer({
port: 8080,
serveDir: './dist',
cors: true,
// Development
watch: true,
injectReload: true,
enableCompression: true,
preferredCompressionMethod: 'brotli',
forceSsl: false,
// Production
forceSsl: true,
spaFallback: true, // Serve index.html for client-side routes
// SEO
sitemap: true,
feed: true,
robots: true,
domain: 'example.com',
blockWaybackMachine: false,
// PWA
appVersion: 'v1.0.0',
manifest: {
name: 'My App',
@@ -83,11 +90,11 @@ await server.start();
### Adding TypedRequest Handlers
```typescript
import { TypedServer, servertools } from '@api.global/typedserver';
import { TypedServer } from '@api.global/typedserver';
import * as typedrequest from '@api.global/typedrequest';
// Define your typed request interface
interface IGetUser {
interface IGetUser extends typedrequest.implementsTR<IGetUser> {
method: 'getUser';
request: { userId: string };
response: { name: string; email: string };
@@ -95,94 +102,46 @@ interface IGetUser {
const server = new TypedServer({ serveDir: './public', cors: true });
// Create a typed router
const typedRouter = new typedrequest.TypedRouter();
// Add a typed handler
typedRouter.addTypedHandler<IGetUser>(
// Add a typed handler directly to the server's router
server.typedrouter.addTypedHandler<IGetUser>(
new typedrequest.TypedHandler('getUser', async (data) => {
// Your logic here
return { name: 'John Doe', email: 'john@example.com' };
})
);
// Attach the router to the server
server.server.addRoute('/api', new servertools.HandlerTypedRouter(typedRouter));
await server.start();
```
### WebSocket Communication with TypedSocket
### Real-Time WebSocket Communication
TypedServer automatically sets up TypedSocket for real-time communication:
```typescript
import { TypedServer } from '@api.global/typedserver';
import * as typedrequest from '@api.global/typedrequest';
import * as typedsocket from '@api.global/typedsocket';
const server = new TypedServer({ serveDir: './public', cors: true });
const typedRouter = new typedrequest.TypedRouter();
await server.start();
// Create WebSocket server attached to the HTTP server
const socketServer = await typedsocket.TypedSocket.createServer(
typedRouter,
server.server
);
// Handle real-time events
interface IChatMessage {
interface IChatMessage extends typedrequest.implementsTR<IChatMessage> {
method: 'sendMessage';
request: { text: string; room: string };
response: { messageId: string; timestamp: number };
}
typedRouter.addTypedHandler<IChatMessage>(
const server = new TypedServer({ serveDir: './public', cors: true });
// Handle real-time messages
server.typedrouter.addTypedHandler<IChatMessage>(
new typedrequest.TypedHandler('sendMessage', async (data) => {
return { messageId: crypto.randomUUID(), timestamp: Date.now() };
})
);
```
## 🛠️ Server Tools
await server.start();
### Custom Route Handlers
```typescript
import { servertools } from '@api.global/typedserver';
const server = new servertools.Server({
cors: true,
domain: 'example.com',
});
// Add a custom route with handler
server.addRoute('/api/hello', new servertools.Handler('GET', async (req, res) => {
res.json({ message: 'Hello, World!' });
}));
// Serve static files from a directory
server.addRoute('/{*splat}', new servertools.HandlerStatic('./public', {
serveIndexHtmlDefault: true,
enableCompression: true,
}));
await server.start(3000);
```
### Proxy Handler
```typescript
import { servertools } from '@api.global/typedserver';
const server = new servertools.Server({ cors: true });
// Proxy requests to another server
server.addRoute('/proxy/{*splat}', new servertools.HandlerProxy({
target: 'https://api.example.com',
}));
await server.start(3000);
// Push messages to connected clients
const connections = await server.typedsocket.findAllTargetConnectionsByTag('typedserver_frontend');
for (const conn of connections) {
// Push to specific clients
}
```
## ☁️ Edge Worker (Cloudflare Workers)
@@ -190,36 +149,44 @@ await server.start(3000);
```typescript
import { EdgeWorker, DomainRouter } from '@api.global/typedserver/edgeworker';
const router = new DomainRouter();
const worker = new EdgeWorker();
router.addDomainInstruction({
// Configure domain routing
worker.domainRouter.addDomainInstruction({
domainPattern: '*.example.com',
originUrl: 'https://origin.example.com',
type: 'cache',
cacheConfig: { maxAge: 3600 },
});
const worker = new EdgeWorker(router);
worker.domainRouter.addDomainInstruction({
domainPattern: 'api.example.com',
originUrl: 'https://api-origin.example.com',
type: 'origin', // Pass through to origin
});
// In your Cloudflare Worker entry point
// Cloudflare Worker entry point
export default {
fetch: (request: Request, env: any, ctx: any) => worker.handleRequest(request, env, ctx),
fetch: worker.fetchFunction.bind(worker),
};
```
## 🔧 Service Worker Client
Manage service workers in your frontend application:
```typescript
import { ServiceWorkerClient } from '@api.global/typedserver/web_serviceworker_client';
import { getServiceworkerClient } from '@api.global/typedserver/web_serviceworker_client';
const swClient = new ServiceWorkerClient();
// Register and manage service worker
await swClient.register('/serviceworker.bundle.js');
// Listen for updates
swClient.onUpdate(() => {
console.log('New version available!');
// Initialize and register service worker
const swClient = await getServiceworkerClient({
pollInterval: 30000, // Poll for updates every 30s
});
// The service worker handles:
// - Cache invalidation from server
// - Offline support
// - Background sync
```
## 📋 Configuration Reference
@@ -233,9 +200,8 @@ swClient.onUpdate(() => {
| `cors` | `boolean` | `true` | Enable CORS headers |
| `watch` | `boolean` | `false` | Watch files for changes |
| `injectReload` | `boolean` | `false` | Inject live reload script into HTML |
| `enableCompression` | `boolean` | `false` | Enable response compression |
| `preferredCompressionMethod` | `'gzip' \| 'deflate' \| 'brotli'` | - | Preferred compression algorithm |
| `forceSsl` | `boolean` | `false` | Redirect HTTP to HTTPS |
| `spaFallback` | `boolean` | `false` | Serve index.html for non-file routes |
| `sitemap` | `boolean` | `false` | Generate sitemap at `/sitemap` |
| `feed` | `boolean` | `false` | Generate RSS feed at `/feed` |
| `robots` | `boolean` | `false` | Serve robots.txt |
@@ -244,16 +210,39 @@ swClient.onUpdate(() => {
| `manifest` | `object` | - | Web App Manifest configuration |
| `publicKey` | `string` | - | SSL certificate |
| `privateKey` | `string` | - | SSL private key |
| `defaultAnswer` | `function` | - | Custom default response handler |
| `feedMetadata` | `object` | - | RSS feed metadata options |
| `blockWaybackMachine` | `boolean` | `false` | Block Wayback Machine archiving |
## 🏗️ Architecture
## 🏗️ Package Exports
```
@api.global/typedserver
├── /backend - Main server exports (TypedServer, servertools)
├── /edgeworker - Cloudflare Workers edge computing
├── /web_inject - Live reload script injection
├── /web_serviceworker - Service Worker implementation
── /web_serviceworker_client - Service Worker client utilities
├── . - Main server (TypedServer)
├── /backend - Alias for main server
├── /edgeworker - Cloudflare Workers edge computing
├── /web_inject - Live reload script injection
── /web_serviceworker - Service Worker implementation
└── /web_serviceworker_client - Service Worker client utilities
```
## 🔄 Utility Servers
Pre-configured server templates for common use cases:
```typescript
import { utilityservers } from '@api.global/typedserver';
// WebsiteServer - optimized for static websites
const websiteServer = new utilityservers.WebsiteServer({
serveDir: './dist',
domain: 'example.com',
});
// ServiceServer - optimized for API services
const serviceServer = new utilityservers.ServiceServer({
cors: true,
});
```
## License and Legal Information

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@api.global/typedserver',
version: '7.8.11',
version: '7.8.18',
description: 'A TypeScript-based project for easy serving of static files with support for live reloading, compression, and typed requests.'
}