@esmap/server
v0.1.0
Published
Import map serving server with deployment API and concurrency-safe updates
Readme
@esmap/server
Import map serving server — deploy API, concurrency-safe updates, and deployment history.
Provides Hono-based HTTP routes. Can run as a standalone server or mount into an existing one.
Installation
pnpm add @esmap/serverQuick Start
import { Hono } from 'hono';
import { createImportMapRoutes, FileSystemStorage } from '@esmap/server';
const app = new Hono();
const storage = new FileSystemStorage('./data');
const routes = createImportMapRoutes(storage);
app.route('/', routes);
export default { port: 3000, fetch: app.fetch };API Endpoints
GET /
Returns the current import map:
curl http://localhost:3000/
# -> { "imports": { "@myorg/checkout": "https://cdn/checkout.js" }, "scopes": {} }PATCH /services/:name
Updates a service URL (deployment):
curl -X PATCH http://localhost:3000/services/@myorg/checkout \
-H 'Content-Type: application/json' \
-d '{"url": "https://cdn/checkout-v2.js"}'DELETE /services/:name
Removes a service from the import map:
curl -X DELETE http://localhost:3000/services/@myorg/checkoutPOST /rollback/:name
Rolls back to the previous deployment:
curl -X POST http://localhost:3000/rollback/@myorg/checkoutGET /history
Queries deployment history:
curl http://localhost:3000/history?limit=20Storage
FileSystemStorage
File system-based storage. Uses an in-memory lock for concurrency control:
import { FileSystemStorage } from '@esmap/server';
const storage = new FileSystemStorage('./data');
// -> ./data/importmap.json (current import map)
// -> ./data/history.json (deployment history, max 1000 entries)Custom Storage
Implement the ImportMapStorage interface to use other backends like S3 or Redis:
import type { ImportMapStorage, DeploymentHistoryEntry } from '@esmap/server';
import type { ImportMap } from '@esmap/shared';
class RedisStorage implements ImportMapStorage {
async read(): Promise<ImportMap | null> {
/* ... */
}
async update(updater: (current: ImportMap) => ImportMap): Promise<ImportMap> {
/* ... */
}
async appendHistory(entry: DeploymentHistoryEntry): Promise<void> {
/* ... */
}
async getHistory(limit?: number): Promise<readonly DeploymentHistoryEntry[]> {
/* ... */
}
}Concurrency Safety
FileSystemStorage.update() is serialized via an in-memory lock. Multiple concurrent deploy requests maintain a consistent import map state.
