@jetstart/shared
v2.3.4
Published
Shared types, protocols, and utilities for JetStart
Downloads
185
Maintainers
Readme
@jetstart/shared
Shared TypeScript types, WebSocket protocol definitions, validation utilities, and constants used across every JetStart package.
Overview
@jetstart/shared is the single source of truth for the JetStart communication contract. All other packages — core, cli, web, logs — import types and constants from here. Nothing about the protocol is duplicated across packages.
src/
├── types/
│ ├── session.ts # Session, SessionStatus, SessionToken, QRCodeData
│ ├── build.ts # BuildConfig, BuildResult, BuildStatus, APKInfo, BuildError
│ ├── device.ts # DeviceInfo, Platform, Architecture
│ └── log.ts # LogEntry, LogLevel, LogSource, LogFilter, LogStats
├── protocols/
│ ├── websocket.ts # All WebSocket message interfaces + WSMessage union type
│ ├── events.ts # EventEmitter-style event definitions
│ └── index.ts
└── utils/
├── constants.ts # Ports, timeouts, size limits, version, error codes
├── validation.ts # isValidProjectName, isValidPackageName, isValidSessionId
├── version-compare.ts # Semantic version comparison
├── colors.ts # Log level color helpers
└── index.tsInstallation
@jetstart/shared is an internal monorepo package. Import it from any workspace:
import {
Session,
BuildConfig,
WSMessage,
DEFAULT_CORE_PORT,
isValidProjectName,
} from '@jetstart/shared';Types
Session
interface Session {
id: string;
token: string;
projectName: string;
projectPath: string;
createdAt: number;
lastActivity: number;
}
enum SessionStatus {
CONNECTING = 'connecting',
CONNECTED = 'connected',
IDLE = 'idle',
DISCONNECTED = 'disconnected',
ERROR = 'error',
}Build
interface BuildConfig {
projectPath: string;
outputPath?: string;
buildType: 'debug' | 'release';
debuggable?: boolean;
minifyEnabled?: boolean;
versionCode?: number;
versionName?: string;
applicationId?: string;
}
interface BuildResult {
success: boolean;
buildTime: number;
apkPath?: string;
apkSize?: number;
errors?: BuildError[];
}
interface APKInfo {
path: string;
size: number;
hash: string;
versionCode: number;
versionName: string;
minSdkVersion: number; // minimum: 24 (Android 7.0)
targetSdkVersion: number; // current target: 34 (Android 14)
applicationId: string;
}Device
interface DeviceInfo {
id: string;
model: string;
platform: Platform;
architecture: Architecture;
androidVersion?: string;
apiLevel?: number;
}
enum Platform { ANDROID = 'android', WEB = 'web' }
enum Architecture { ARM64 = 'arm64', X86_64 = 'x86_64', X86 = 'x86' }Logging
interface LogEntry {
id: string;
timestamp: number;
level: LogLevel;
tag: string;
message: string;
source: LogSource;
metadata?: Record<string, unknown>;
}
enum LogLevel { VERBOSE, DEBUG, INFO, WARN, ERROR, FATAL }
enum LogSource { CLI, CORE, CLIENT, BUILD, NETWORK, SYSTEM }WebSocket Protocol
All messages extend BaseMessage:
interface BaseMessage {
type: string;
timestamp: number;
sessionId?: string;
}
type WSMessage = ClientMessage | CoreMessage;Device / Browser → Core
| type | Key fields | Description |
|---|---|---|
| client:connect | sessionId, token, deviceInfo | Authenticate with session credentials |
| client:status | status: SessionStatus | Send a status update |
| client:log | log: LogEntry | Forward a device log to the server |
| client:heartbeat | — | Keep-alive ping |
| client:disconnect | reason? | Graceful disconnect |
| client:click | action, elementType, elementText? | UI interaction event from web emulator |
Core → Device / Browser
| type | Key fields | Description |
|---|---|---|
| core:connected | projectName | Authentication accepted |
| core:build-start | — | Gradle build has started |
| core:build-status | status: BuildStatus | Mid-build progress update |
| core:build-complete | apkInfo: APKInfo, downloadUrl | APK is ready |
| core:build-error | error, details? | Build failed |
| core:reload | reloadType: 'full' \| 'hot' | Request an app reload |
| core:dex-reload | dexBase64, classNames: string[] | Hot reload DEX patch for Android |
| core:js-update | jsBase64, sourceFile, byteSize | ES module update for the web emulator |
| core:log | log: LogEntry | Broadcast a device log to dashboard clients |
| core:disconnect | reason | Server is shutting down |
Constants
// Default ports
DEFAULT_CORE_PORT = 8765 // HTTP server
DEFAULT_WS_PORT = 8766 // WebSocket server
DEFAULT_LOGS_PORT = 8767 // Logs server
// WebSocket behaviour
WS_HEARTBEAT_INTERVAL = 30_000 // ms between heartbeat pings
WS_RECONNECT_DELAY = 5_000 // ms before reconnect attempt
WS_MAX_RECONNECT_ATTEMPTS = 5
// Session lifecycle
SESSION_TOKEN_EXPIRY = 3_600_000 // 1 hour
SESSION_CLEANUP_INTERVAL = 60_000 // 1 minute
SESSION_IDLE_TIMEOUT = 1_800_000 // 30 minutes
// Build limits
BUILD_CACHE_SIZE_LIMIT = 1_073_741_824 // 1 GB
BUILD_TIMEOUT = 300_000 // 5 minutes
MAX_CONCURRENT_BUILDS = 3
// File limits
MAX_APK_SIZE = 104_857_600 // 100 MB
MAX_LOG_ENTRIES = 10_000
// Android targets
MIN_ANDROID_API_LEVEL = 24 // Android 7.0
TARGET_ANDROID_API_LEVEL = 34 // Android 14
// Version
JETSTART_VERSION = '0.1.0'Validation
import { isValidProjectName, isValidPackageName, isValidSessionId } from '@jetstart/shared';
// Letters, numbers, hyphens, underscores; must start with a letter; 1–64 chars
isValidProjectName('my-app') // true
isValidProjectName('123bad') // false
// Reverse-domain format, at least two segments
isValidPackageName('com.example.app') // true
isValidPackageName('example') // false
isValidSessionId(sessionId) // validates generated session ID formatWebSocket State & Error Types
enum WSState {
CONNECTING = 'connecting',
CONNECTED = 'connected',
DISCONNECTING = 'disconnecting',
DISCONNECTED = 'disconnected',
ERROR = 'error',
}
enum WSErrorCode {
CONNECTION_FAILED = 'connection_failed',
AUTHENTICATION_FAILED = 'authentication_failed',
TIMEOUT = 'timeout',
INVALID_MESSAGE = 'invalid_message',
SESSION_EXPIRED = 'session_expired',
UNKNOWN = 'unknown',
}License
MIT