Packages
Packages
Reference guide for all 12 shared packages in the Realtime Platform monorepo.
The Realtime Platform monorepo contains 12 shared packages under packages/. Each package is independently versioned and built, with Turborepo managing the dependency graph.
@realtime/shared-types
TypeScript interfaces shared across all packages. No runtime code — types only.
Key Types:
| Type | Description |
|---|---|
RealtimeEvent | Normalized event envelope |
TopicDefinition | Topic registry record |
SchemaDefinition | Versioned JSON Schema record |
DomainMapping | Database-to-topic mapping config |
SubscriptionFilter | Client-side event filter |
EventEnvelope | Client-facing event wrapper |
WebhookEndpoint | Webhook endpoint configuration |
WebhookDeliveryLog | Delivery attempt record |
Application | Multi-tenant application record |
User, Role, Permission | Auth system types |
Deployment, DeploymentItem | Environment promotion types |
import type { RealtimeEvent, TopicDefinition } from '@realtime/shared-types';@realtime/shared-utils
Common utilities used across the platform.
Error Classes:
import { NotFoundError, ConflictError, ValidationError } from '@realtime/shared-utils';
throw new NotFoundError('Topic not found: session.status');
throw new ConflictError('Document revision mismatch');
throw new ValidationError('Invalid topic name format');Object Helpers:
import { deepMerge, deepClone, pick, omit } from '@realtime/shared-utils';
const merged = deepMerge(base, override);
const cloned = deepClone(original);
const subset = pick(obj, ['name', 'email']);
const filtered = omit(obj, ['password']);ID Generation:
import { generatePrefixedId } from '@realtime/shared-utils';
const eventId = generatePrefixedId('evt'); // evt_a1b2c3d4
const docId = generatePrefixedId('doc'); // doc_x9y8z7w6Date Helpers:
import { formatISO, relativeTimestamp } from '@realtime/shared-utils';@realtime/shared-config
Zod-validated environment configuration. Reads from environment variables and provides a typed config object.
import { getConfig } from '@realtime/shared-config';
const config = getConfig();
// config.port → 3000
// config.logLevel → 'debug'
// config.redis.url → 'redis://localhost:6379'
// config.postgres.* → database connection detailsIf a required variable is missing or invalid, the validation throws a clear error at startup.
@realtime/observability
Logging and Prometheus metrics.
Logging (pino):
import { getLogger } from '@realtime/observability';
const logger = getLogger();
logger.info('Server started');
logger.error({ err }, 'Request failed');Metrics (Prometheus):
import { createCounter, createHistogram, createGauge } from '@realtime/observability';
const eventsReceived = createCounter({
name: 'realtime_events_received_total',
help: 'Total events received',
labelNames: ['topic', 'source'],
});
eventsReceived.inc({ topic: 'session.status', source: 'database' });All metric factories are idempotent — calling createCounter with the same name returns the existing metric.
@realtime/redis-layer
Redis client, Pub/Sub, RedisJSON, and key patterns.
RedisJSON Client:
import { RedisJsonClient } from '@realtime/redis-layer';
await client.set('syncdoc:data:session:doc1', { status: 'active' });
const doc = await client.get('syncdoc:data:session:doc1');
await client.merge('syncdoc:data:session:doc1', { notes: 'updated' });
await client.del('syncdoc:data:session:doc1');
// TTL management (used by HybridDocumentService for cache expiry)
await client.expire('syncdoc:data:session:doc1', 600);
// Access underlying ioredis client for advanced operations
const raw = client.getRawClient();Pub/Sub Manager:
import { PubSubManager } from '@realtime/redis-layer';
const pubsub = new PubSubManager(redisUrl);
pubsub.subscribe('realtime:event:session.status', (event) => {
console.log('Received:', event);
});
pubsub.publish('realtime:event:session.status', eventData);Key Patterns:
import { RedisKeys } from '@realtime/redis-layer';
RedisKeys.syncDocument('session', 'doc1'); // syncdoc:data:session:doc1
RedisKeys.eventChannel('session.status'); // realtime:event:session.statusQueue Manager (BullMQ):
import { QueueManager } from '@realtime/redis-layer';
const queue = QueueManager.createQueue('webhook-delivery');
await queue.add('deliver', { webhookId: 'wh_123', event: {...} });@realtime/auth
JWT signing/verification, signing key management, and Express middleware.
import { JwtService, SigningKeyStore } from '@realtime/auth';
const keyStore = new SigningKeyStore();
const jwt = new JwtService(keyStore);
const token = jwt.sign({ sub: 'user123', permissions: ['subscribe'] });
const claims = jwt.verify(token);Express Middleware:
import { authMiddleware } from '@realtime/auth';
app.use('/api', authMiddleware(jwtService));
// req.user is now populated with JWT claimsPermission Roles: admin, service, client
@realtime/event-router
Event normalization, routing, filtering, and subscription management.
Components:
| Class | Purpose |
|---|---|
EventNormalizer | Converts raw input to RealtimeEvent with unique IDs |
EventPublisher | Publishes events to Redis Pub/Sub |
EventFilter | Applies subscription filters (equality, in operator) |
SubscriptionRegistry | In-memory subscription store by topic and client |
EventRouter | Orchestrates the full pipeline |
import { EventRouter } from '@realtime/event-router';
const router = new EventRouter({ publisher, normalizer, filter, registry });
await router.route(rawEvent);@realtime/topic-registry
Topic CRUD and validation.
import { TopicRegistryService } from '@realtime/topic-registry';
const service = new TopicRegistryService(store);
await service.create({ name: 'session.status', description: '...', owner: 'team-a' });
const topics = await service.list();
const topic = await service.get('session.status');Validation Rules:
- Names must be dot-separated, lowercase
- Format:
segment.segment(letters, numbers, dots) - Minimum one dot separator
@realtime/schema-registry
Schema registration, versioning, validation, and backward compatibility checking.
import { SchemaRegistryService } from '@realtime/schema-registry';
const service = new SchemaRegistryService(store);
await service.register({
topic: 'session.status',
schema: { type: 'object', properties: { ... } },
compatibilityMode: 'backward',
});
const result = await service.validate('session.status', payload);
// { valid: true } or { valid: false, errors: [...] }Compatibility Modes: backward (default), none
@realtime/metrics
Prometheus metric collectors, dashboard aggregation, and hot topic analysis.
import { MetricsCollector, DashboardMetrics, HotTopicsAnalyzer } from '@realtime/metrics';
const dashboard = new DashboardMetrics(collector);
const stats = dashboard.getStats();
// { delivery: {...}, pipeline: {...}, reliability: {...} }
const hot = new HotTopicsAnalyzer();
hot.recordEvent('session.status');
const hotTopics = hot.getHotTopics();
// [{ topic, eventsPerSec, subscriberCount, p95Fanout }]@realtime/database
Knex migration system and PostgreSQL connection management.
import { getDatabase, closeDatabase, runMigrations } from '@realtime/database';
const db = getDatabase(); // Singleton Knex instance
await runMigrations(); // Apply pending migrations
await closeDatabase(); // Graceful shutdownMigration Commands:
pnpm --filter @realtime/database migrate:latest # Apply all pending
pnpm --filter @realtime/database migrate:status # Check status
pnpm --filter @realtime/database migrate:rollback # Rollback last batch
pnpm --filter @realtime/database migrate:make name # Create new migrationConnection Pool: min 2, max 10
@smarterservices/realtime (SDK)
Client SDK for browser and Node.js. See the full SDK documentation.