Create Assets middleware with automatic source detection.
Performs environment probing to determine optimal asset serving mode. Configuration applies only to filesystem mode - other modes ignore options and operate based on environment capabilities.
Optional
options: AssetsOptions = {}Configuration options
// Automatic mode detection with sensible defaults
const assets = new Assets();
router.use(assets);
// → Uses 'public' directory in filesystem mode
// → Auto-detects SEA/global modes when available
Cached list of available assets.
Contains web-normalized paths (starting with '/') of all discoverable assets. Population strategy varies by mode: immediate for SEA/global, asynchronous for filesystem.
Full resolved path to assets directory.
Only used in filesystem mode for file operations. Null in SEA/global modes where assets are served from memory sources.
Current asset serving mode.
Reflects the detected and active asset source. Set during initialization based on environment capabilities and available sources.
Gets the middleware handler function.
Returns the function that will be executed when the middleware runs. This getter provides read-only access to the handler function.
The handler function
const middleware = new Middleware((ctx) => {
console.log('Processing request');
});
const handler = middleware.handler;
console.log(typeof handler); // 'function'
// Can be used for testing or introspection
if (handler.toString().includes('console.log')) {
console.log('This middleware includes logging');
}
Gets the middleware identifier.
Returns the identifier string or null if no identifier was set. This getter provides read-only access to the identifier.
The identifier or null if not set
// Middleware with identifier
const authMiddleware = new Middleware((ctx) => {}, 'auth');
console.log(authMiddleware.identifier); // 'auth'
// Middleware without identifier
const loggingMiddleware = new Middleware((ctx) => {});
console.log(loggingMiddleware.identifier); // null
// Use identifier for conditional logic
if (middleware.identifier === 'authentication') {
console.log('This is an authentication middleware');
}
Executes the middleware handler with the given context.
This method invokes the middleware handler function, passing the context object as the first argument. The method supports both synchronous and asynchronous handlers, always returning a Promise.
Execution Flow:
Error Handling: Any errors thrown by the handler (synchronous or asynchronous) are propagated to the caller. This allows middleware errors to be handled by the calling code.
The request/response context
Promise that resolves when the handler completes
const middleware = new Middleware((ctx) => {
console.log(`Processing ${ctx.method} request to ${ctx.path}`);
ctx.data.processedAt = new Date().toISOString();
});
const url = new URL('http://localhost/api/users');
const ctx = new Context('GET', url, new Headers());
// Execute middleware
await middleware.execute(ctx);
console.log(ctx.data.processedAt); // ISO timestamp
// Async middleware
const asyncMiddleware = new Middleware(async (ctx) => {
await new Promise(resolve => setTimeout(resolve, 100));
ctx.data.asyncProcessed = true;
});
await asyncMiddleware.execute(ctx);
console.log(ctx.data.asyncProcessed); // true
// Error handling
const errorMiddleware = new Middleware((ctx) => {
throw new Error('Middleware error');
});
try {
await errorMiddleware.execute(ctx);
} catch (error) {
console.error('Middleware failed:', error.message);
}
// Invalid context
try {
await middleware.execute(null);
} catch (error) {
console.error(error.message); // "Context must be a Context instance"
}
Checks if this middleware has the same identifier as another middleware.
This method is used for duplicate detection and middleware comparison. Two middleware are considered to have the same identifier if:
Note: Middleware with null identifiers are never considered equal, even if both have null identifiers.
The other middleware to compare with
True if both middlewares have the same non-null identifier
const auth1 = new Middleware((ctx) => {}, 'authentication');
const auth2 = new Middleware((ctx) => {}, 'authentication');
const logging = new Middleware((ctx) => {}, 'logging');
const generic = new Middleware((ctx) => {});
// Same identifier
auth1.hasSameIdentifier(auth2); // true
auth2.hasSameIdentifier(auth1); // true
// Different identifiers
auth1.hasSameIdentifier(logging); // false
logging.hasSameIdentifier(auth1); // false
// Null identifiers (never equal)
auth1.hasSameIdentifier(generic); // false
generic.hasSameIdentifier(auth1); // false
generic.hasSameIdentifier(new Middleware((ctx) => {})); // false
// Invalid parameters
auth1.hasSameIdentifier(null); // false
auth1.hasSameIdentifier({}); // false
auth1.hasSameIdentifier('string'); // false
// Use for duplicate prevention
function addMiddlewareIfNotExists(middlewareList, newMiddleware) {
const hasDuplicate = middlewareList.some(existing =>
existing.hasSameIdentifier(newMiddleware)
);
if (!hasDuplicate) {
middlewareList.push(newMiddleware);
}
}
Assets - Multi-source static file serving middleware.
Implements transparent asset serving with automatic source detection across three deployment modes: SEA embedded resources, JavaScript variables, and traditional filesystem. Zero-configuration operation with consistent security model and performance characteristics.
Priority-Based Mode Selection:
Security Model:
Error Handling:
Example: Basic Usage
Example: Custom Directory
Example: SEA Deployment
Example: Global Variables Mode