@spooled/sdk 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.ts","../src/errors.ts","../src/utils/casing.ts","../src/utils/retry.ts","../src/utils/http.ts","../src/utils/circuit-breaker.ts","../src/resources/auth.ts","../src/utils/failure.ts","../src/utils/paging.ts","../src/resources/jobs.ts","../src/resources/queues.ts","../src/resources/workers.ts","../src/resources/schedules.ts","../src/resources/workflows.ts","../src/resources/webhooks.ts","../src/resources/api-keys.ts","../src/resources/organizations.ts","../src/resources/billing.ts","../src/resources/dashboard.ts","../src/resources/health.ts","../src/resources/metrics.ts","../src/resources/admin.ts","../src/resources/webhook-ingestion.ts","../src/realtime/event-map.ts","../src/realtime/websocket.ts","../src/realtime/sse.ts","../src/realtime/index.ts","../src/grpc/loader.ts","../src/grpc/encode.ts","../src/grpc/streaming.ts","../src/grpc/client.ts","../src/client.ts","../src/types/common.ts","../src/grpc/types.ts","../src/worker/worker.ts"],"names":["CircuitState","status","dirname","fileURLToPath","join","existsSync","protoLoader","grpc","grpc2","credentials","GrpcJobStatus","osHostname"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * SDK Configuration\n *\n * Defines configuration types and defaults for the Spooled SDK.\n */\n\nimport type { CircuitBreakerOptions } from \"./utils/circuit-breaker.js\";\n\n/** Retry configuration options */\nexport interface RetryConfig {\n /** Maximum number of retry attempts (default: 3) */\n maxRetries: number;\n /** Base delay in milliseconds for exponential backoff (default: 1000) */\n baseDelay: number;\n /** Maximum delay in milliseconds (default: 30000) */\n maxDelay: number;\n /** Exponential backoff factor (default: 2) */\n factor: number;\n /** Whether to add jitter to delays (default: true) */\n jitter: boolean;\n /** Custom function to determine if an error is retryable */\n retryOn?: (error: Error, attempt: number) => boolean;\n}\n\n/** Circuit breaker configuration options */\nexport interface CircuitBreakerConfig {\n /** Whether circuit breaker is enabled (default: true) */\n enabled: boolean;\n /** Number of failures before opening the circuit (default: 5) */\n failureThreshold: number;\n /** Number of successes in half-open state to close circuit (default: 3) */\n successThreshold: number;\n /** Time in milliseconds to wait before trying again after opening (default: 30000) */\n timeout: number;\n}\n\n/** Debug logging function type */\nexport type DebugFn = (message: string, meta?: unknown) => void;\n\n/** Main SDK configuration options */\nexport interface SpooledClientConfig {\n /** API key for authentication (starts with sp_live_, sp_test_, sk_live_, or sk_test_) */\n apiKey?: string;\n /** JWT access token (alternative to API key) */\n accessToken?: string;\n /** JWT refresh token for automatic token renewal */\n refreshToken?: string;\n /** Admin API key (for /api/v1/admin/* endpoints; uses X-Admin-Key header) */\n adminKey?: string;\n /** Base URL for the REST API (default: https://api.spooled.cloud) */\n baseUrl?: string;\n /** WebSocket URL for realtime events (default: derived from baseUrl, e.g., wss://api.spooled.cloud) */\n wsUrl?: string;\n /** gRPC server address (default: grpc.spooled.cloud:443) */\n grpcAddress?: string;\n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n /** Number of retry attempts (shorthand for retry.maxRetries) */\n retries?: number;\n /** Base retry delay in milliseconds (shorthand for retry.baseDelay) */\n retryDelay?: number;\n /** Full retry configuration */\n retry?: Partial<RetryConfig>;\n /**\n * Circuit breaker configuration. Besides the thresholds it takes\n * `isFailure` (which errors count as failures) and `onStateChange`.\n */\n circuitBreaker?: Partial<CircuitBreakerOptions>;\n /** Additional headers to include in all requests */\n headers?: Record<string, string>;\n /** Custom fetch implementation (for testing or special runtimes) */\n fetch?: typeof fetch;\n /** Custom user agent string */\n userAgent?: string;\n /** Enable debug logging */\n debug?: boolean | DebugFn;\n /** Whether to automatically refresh tokens when they expire (default: true) */\n autoRefreshToken?: boolean;\n}\n\n/** Resolved configuration with all defaults applied */\nexport interface ResolvedConfig {\n apiKey?: string;\n accessToken?: string;\n refreshToken?: string;\n adminKey?: string;\n baseUrl: string;\n wsUrl: string;\n grpcAddress: string;\n timeout: number;\n retry: RetryConfig;\n circuitBreaker: CircuitBreakerOptions;\n headers: Record<string, string>;\n fetch: typeof fetch;\n userAgent: string;\n debug: DebugFn | null;\n autoRefreshToken: boolean;\n}\n\n/** Default configuration values */\nexport const DEFAULT_CONFIG = {\n baseUrl: \"https://api.spooled.cloud\",\n wsUrl: \"wss://api.spooled.cloud\",\n grpcAddress: \"grpc.spooled.cloud:443\",\n timeout: 30000,\n retry: {\n maxRetries: 3,\n baseDelay: 1000,\n maxDelay: 30000,\n factor: 2,\n jitter: true,\n } satisfies RetryConfig,\n circuitBreaker: {\n enabled: true,\n failureThreshold: 5,\n successThreshold: 3,\n timeout: 30000,\n } satisfies CircuitBreakerConfig,\n userAgent: \"@spooled/sdk-nodejs/1.4.0\",\n autoRefreshToken: true,\n} as const;\n\n/** SDK version */\nexport const SDK_VERSION = \"1.4.0\";\n\n/** API version prefix */\nexport const API_VERSION = \"v1\";\n\n/** API base path */\nexport const API_BASE_PATH = `/api/${API_VERSION}`;\n\n/**\n * Trim surrounding whitespace from a credential string and treat an\n * all-whitespace input as unset. Mirrors the trim policy in the Go, PHP,\n * and Python SDKs so behavior is consistent across languages.\n */\nfunction normalizeCredential(value: string | undefined): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed === \"\" ? undefined : trimmed;\n}\n\n/**\n * Resolve configuration by merging user options with defaults\n */\nexport function resolveConfig(options: SpooledClientConfig): ResolvedConfig {\n // Create debug function\n let debugFn: DebugFn | null = null;\n if (options.debug === true) {\n debugFn = (message: string, meta?: unknown) => {\n // eslint-disable-next-line no-console\n console.log(`[spooled-sdk] ${message}`, meta !== undefined ? meta : \"\");\n };\n } else if (typeof options.debug === \"function\") {\n debugFn = options.debug;\n }\n\n // Merge retry config\n const retry: RetryConfig = {\n ...DEFAULT_CONFIG.retry,\n ...options.retry,\n // Allow shorthand overrides\n ...(options.retries !== undefined && { maxRetries: options.retries }),\n ...(options.retryDelay !== undefined && { baseDelay: options.retryDelay }),\n };\n\n // Merge circuit breaker config\n const circuitBreaker: CircuitBreakerOptions = {\n ...DEFAULT_CONFIG.circuitBreaker,\n ...options.circuitBreaker,\n };\n\n // Build headers\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...options.headers,\n };\n\n // Resolve base URL first\n const baseUrl = options.baseUrl ?? DEFAULT_CONFIG.baseUrl;\n\n // Derive WebSocket URL from base URL if not explicitly set\n // Replace http(s):// with ws(s)://\n const derivedWsUrl = baseUrl.replace(/^http/, \"ws\");\n const wsUrl = options.wsUrl ?? derivedWsUrl;\n\n // Trim whitespace (including a stray trailing '\\n') from every credential.\n // Node's `undici` fetch rejects `Authorization: Bearer <key>\\n` with an\n // opaque `TypeError: HeaderValue` and users routinely paste keys from\n // `.env` files that include a newline; normalizing here keeps behavior\n // consistent with the Go, PHP, and Python SDKs.\n return {\n apiKey: normalizeCredential(options.apiKey),\n accessToken: normalizeCredential(options.accessToken),\n refreshToken: normalizeCredential(options.refreshToken),\n adminKey: normalizeCredential(options.adminKey),\n baseUrl,\n wsUrl,\n grpcAddress: options.grpcAddress ?? DEFAULT_CONFIG.grpcAddress,\n timeout: options.timeout ?? DEFAULT_CONFIG.timeout,\n retry,\n circuitBreaker,\n headers,\n fetch: options.fetch ?? globalThis.fetch,\n userAgent: options.userAgent ?? DEFAULT_CONFIG.userAgent,\n debug: debugFn,\n autoRefreshToken:\n options.autoRefreshToken ?? DEFAULT_CONFIG.autoRefreshToken,\n };\n}\n\n/**\n * Validate configuration options\n * @throws Error if configuration is invalid\n */\nexport function validateConfig(config: ResolvedConfig): void {\n // Must have at least one auth method. An admin key alone is enough: the\n // /admin/* endpoints authenticate with X-Admin-Key only, so an admin-only\n // client (`client.admin.*`) is legitimate.\n if (!config.apiKey && !config.accessToken && !config.adminKey) {\n throw new Error(\n \"SpooledClient requires either apiKey or accessToken for authentication (or adminKey for admin-only use)\",\n );\n }\n\n // Validate API key format if provided\n // Accept both sp_ (new standard) and sk_ (legacy) prefixes\n if (\n config.apiKey &&\n !config.apiKey.startsWith(\"sp_\") &&\n !config.apiKey.startsWith(\"sk_\")\n ) {\n throw new Error(\n \"Invalid API key format. API keys should start with sp_live_, sp_test_, sk_live_, or sk_test_\",\n );\n }\n\n // Validate baseUrl\n if (\n !config.baseUrl.startsWith(\"http://\") &&\n !config.baseUrl.startsWith(\"https://\")\n ) {\n throw new Error(\"baseUrl must start with http:// or https://\");\n }\n\n // Validate timeout\n if (config.timeout <= 0) {\n throw new Error(\"timeout must be a positive number\");\n }\n\n // Validate retry config\n if (config.retry.maxRetries < 0) {\n throw new Error(\"retry.maxRetries must be non-negative\");\n }\n if (config.retry.baseDelay <= 0) {\n throw new Error(\"retry.baseDelay must be positive\");\n }\n if (config.retry.maxDelay < config.retry.baseDelay) {\n throw new Error(\"retry.maxDelay must be >= retry.baseDelay\");\n }\n if (config.retry.factor < 1) {\n throw new Error(\"retry.factor must be >= 1\");\n }\n\n // Validate circuit breaker config\n if (config.circuitBreaker.enabled) {\n if (config.circuitBreaker.failureThreshold <= 0) {\n throw new Error(\"circuitBreaker.failureThreshold must be positive\");\n }\n if (config.circuitBreaker.successThreshold <= 0) {\n throw new Error(\"circuitBreaker.successThreshold must be positive\");\n }\n if (config.circuitBreaker.timeout <= 0) {\n throw new Error(\"circuitBreaker.timeout must be positive\");\n }\n }\n}\n","/**\n * Custom Error Classes\n *\n * Provides a hierarchy of error types for the Spooled SDK.\n */\n\n/** Error response body from the API */\nexport interface ApiErrorBody {\n code: string;\n message: string;\n details?: Record<string, unknown>;\n}\n\n/**\n * Rate limit information parsed from headers.\n *\n * Authenticated responses that went through the plan rate limiter carry\n * `X-RateLimit-Limit`, `-Remaining`, `-Reset` and `-Scope` (API 0.1.122+); a\n * 429 adds `Retry-After`. Every field is optional: the headers are left out\n * when no rate-limit check ran (public and admin routes, a server without\n * Redis, older servers).\n */\nexport interface RateLimitInfo {\n /**\n * The limit the other fields describe: the plan burst (organization token\n * bucket) or an API key's own requests per minute.\n */\n limit?: number;\n /** Whole requests left after this one */\n remaining?: number;\n /**\n * When `remaining` next goes up (`X-RateLimit-Reset`, a Unix time in\n * seconds; the current time while the bucket is full).\n */\n reset?: Date;\n /** Seconds to wait before retrying (`Retry-After`, on a 429) */\n retryAfter?: number;\n /**\n * Which limit the headers describe (`X-RateLimit-Scope`): `organization`\n * (the plan's token bucket) or `api_key` (the key's `rateLimit`).\n */\n scope?: \"organization\" | \"api_key\" | (string & {});\n}\n\n/**\n * Base error class for all Spooled SDK errors\n */\nexport class SpooledError extends Error {\n /** HTTP status code (if applicable) */\n readonly statusCode: number;\n /** Error code from API response */\n readonly code: string;\n /** Additional error details */\n readonly details?: Record<string, unknown>;\n /** Request ID for debugging */\n readonly requestId?: string;\n /** Original cause of the error */\n readonly cause?: Error;\n\n constructor(\n message: string,\n statusCode: number = 0,\n code: string = \"UNKNOWN_ERROR\",\n details?: Record<string, unknown>,\n requestId?: string,\n cause?: Error,\n ) {\n super(message);\n this.name = \"SpooledError\";\n this.statusCode = statusCode;\n this.code = code;\n this.details = details;\n this.requestId = requestId;\n this.cause = cause;\n\n // Maintain proper stack trace in V8 environments\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n /**\n * Whether this error is retryable.\n *\n * Only 408 (Request Timeout) is retryable among the plain 4xx statuses: the\n * server gave up waiting for the request, so it never ran. Subclasses\n * override this (5xx, network, timeout, rate limit).\n */\n isRetryable(): boolean {\n return this.statusCode === 408;\n }\n\n /** Convert to plain object for logging */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n statusCode: this.statusCode,\n code: this.code,\n details: this.details,\n requestId: this.requestId,\n };\n }\n}\n\n/**\n * Authentication error (401)\n * Thrown when authentication fails (invalid/expired token or API key)\n */\nexport class AuthenticationError extends SpooledError {\n constructor(\n message: string = \"Authentication failed\",\n code: string = \"AUTHENTICATION_FAILED\",\n details?: Record<string, unknown>,\n requestId?: string,\n ) {\n super(message, 401, code, details, requestId);\n this.name = \"AuthenticationError\";\n }\n}\n\n/**\n * Authorization error (403)\n * Thrown when the authenticated user lacks permission\n */\nexport class AuthorizationError extends SpooledError {\n constructor(\n message: string = \"Access denied\",\n code: string = \"ACCESS_DENIED\",\n details?: Record<string, unknown>,\n requestId?: string,\n ) {\n super(message, 403, code, details, requestId);\n this.name = \"AuthorizationError\";\n }\n}\n\n/**\n * Not found error (404)\n * Thrown when a requested resource doesn't exist\n */\nexport class NotFoundError extends SpooledError {\n constructor(\n message: string = \"Resource not found\",\n code: string = \"NOT_FOUND\",\n details?: Record<string, unknown>,\n requestId?: string,\n ) {\n super(message, 404, code, details, requestId);\n this.name = \"NotFoundError\";\n }\n}\n\n/**\n * Conflict error (409)\n * Thrown when there's a conflict (e.g., duplicate resource)\n */\nexport class ConflictError extends SpooledError {\n constructor(\n message: string = \"Conflict\",\n code: string = \"CONFLICT\",\n details?: Record<string, unknown>,\n requestId?: string,\n ) {\n super(message, 409, code, details, requestId);\n this.name = \"ConflictError\";\n }\n}\n\n/**\n * Validation error (400 or 422)\n * Thrown when request validation fails.\n *\n * The API answers a field-rule failure (length, range) with 400 but a missing\n * or mistyped JSON field with 422; both are the caller's request being invalid,\n * so both surface as this class. `statusCode` tells them apart.\n */\nexport class ValidationError extends SpooledError {\n constructor(\n message: string = \"Validation failed\",\n code: string = \"VALIDATION_ERROR\",\n details?: Record<string, unknown>,\n requestId?: string,\n statusCode: 400 | 422 = 400,\n ) {\n super(message, statusCode, code, details, requestId);\n this.name = \"ValidationError\";\n }\n}\n\n/**\n * Payload too large error (413)\n * Thrown when request body exceeds size limit\n */\nexport class PayloadTooLargeError extends SpooledError {\n constructor(\n message: string = \"Request payload too large\",\n code: string = \"PAYLOAD_TOO_LARGE\",\n details?: Record<string, unknown>,\n requestId?: string,\n ) {\n super(message, 413, code, details, requestId);\n this.name = \"PayloadTooLargeError\";\n }\n}\n\n/** Plan-limit wording the API uses (\"Daily job limit reached\", \"queues limit reached (5/5)\"). */\nconst QUOTA_MESSAGE = /\\blimit reached\\b/i;\n\n/**\n * Rate limit error (429)\n * Thrown when rate limit is exceeded, or a plan quota is (see `isQuota`)\n */\nexport class RateLimitError extends SpooledError {\n /** Rate limit information */\n readonly rateLimitInfo: RateLimitInfo;\n\n constructor(\n message: string = \"Rate limit exceeded\",\n code: string = \"RATE_LIMIT_EXCEEDED\",\n rateLimitInfo: RateLimitInfo = {},\n details?: Record<string, unknown>,\n requestId?: string,\n ) {\n super(message, 429, code, details, requestId);\n this.name = \"RateLimitError\";\n this.rateLimitInfo = rateLimitInfo;\n }\n\n /**\n * True when this 429 is a plan quota or limit (daily job cap, active jobs,\n * queue/worker/webhook caps) rather than per-second rate limiting.\n *\n * A quota does not clear for minutes or hours, so retrying it only blocks the\n * caller for the whole backoff and, via the circuit breaker, takes every\n * other call on the client down with it. It is never retried and never\n * counted as a circuit breaker failure.\n *\n * Detection: the `QUOTA_EXCEEDED` code, or, for older plan-limit paths that\n * answer with plain text wrapped as `RATE_LIMIT_EXCEEDED`, a \"... limit\n * reached\" message that carries no `Retry-After`.\n */\n get isQuota(): boolean {\n if (this.code === \"QUOTA_EXCEEDED\") {\n return true;\n }\n return (\n this.rateLimitInfo.retryAfter === undefined &&\n QUOTA_MESSAGE.test(this.message)\n );\n }\n\n override isRetryable(): boolean {\n return !this.isQuota;\n }\n\n /** Get the number of seconds to wait before retrying */\n getRetryAfter(): number {\n if (this.rateLimitInfo.retryAfter !== undefined) {\n return this.rateLimitInfo.retryAfter;\n }\n if (this.rateLimitInfo.reset) {\n const now = Date.now();\n const resetTime = this.rateLimitInfo.reset.getTime();\n return Math.max(0, Math.ceil((resetTime - now) / 1000));\n }\n return 60; // Default to 60 seconds\n }\n\n override toJSON(): Record<string, unknown> {\n return {\n ...super.toJSON(),\n rateLimitInfo: this.rateLimitInfo,\n };\n }\n}\n\n/**\n * Server error (5xx)\n * Thrown when the server encounters an error\n */\nexport class ServerError extends SpooledError {\n constructor(\n message: string = \"Server error\",\n statusCode: number = 500,\n code: string = \"SERVER_ERROR\",\n details?: Record<string, unknown>,\n requestId?: string,\n ) {\n super(message, statusCode, code, details, requestId);\n this.name = \"ServerError\";\n }\n\n override isRetryable(): boolean {\n return true;\n }\n}\n\n/**\n * Network error\n * Thrown when a network request fails (no response received)\n */\nexport class NetworkError extends SpooledError {\n constructor(message: string = \"Network request failed\", cause?: Error) {\n super(message, 0, \"NETWORK_ERROR\", undefined, undefined, cause);\n this.name = \"NetworkError\";\n }\n\n override isRetryable(): boolean {\n return true;\n }\n}\n\n/**\n * Timeout error\n * Thrown when a request times out\n */\nexport class TimeoutError extends SpooledError {\n /** Timeout duration in milliseconds */\n readonly timeoutMs: number;\n\n constructor(message: string = \"Request timed out\", timeoutMs: number = 0) {\n super(message, 0, \"TIMEOUT\", { timeoutMs });\n this.name = \"TimeoutError\";\n this.timeoutMs = timeoutMs;\n }\n\n override isRetryable(): boolean {\n return true;\n }\n}\n\n/**\n * Circuit breaker open error\n * Thrown when the circuit breaker is open and rejecting requests\n */\nexport class CircuitBreakerOpenError extends SpooledError {\n constructor(message: string = \"Circuit breaker is open\") {\n super(message, 0, \"CIRCUIT_BREAKER_OPEN\");\n this.name = \"CircuitBreakerOpenError\";\n }\n\n override isRetryable(): boolean {\n return false; // Should wait for circuit to close\n }\n}\n\n/**\n * Unsupported operation error\n * Thrown by SDK methods whose route the Spooled API does not provide (or\n * always rejects). It is raised before any network call, so code that still\n * calls such a method fails loudly with an explanation instead of a 404.\n */\nexport class UnsupportedOperationError extends SpooledError {\n /** The SDK method that is not supported, e.g. `ingest.github` */\n readonly operation: string;\n\n constructor(operation: string, reason: string) {\n super(\n `${operation} is not supported by the Spooled API: ${reason}`,\n 0,\n \"UNSUPPORTED_OPERATION\",\n { operation },\n );\n this.name = \"UnsupportedOperationError\";\n this.operation = operation;\n }\n}\n\n/**\n * Parse rate limit headers from a Response\n */\nexport function parseRateLimitHeaders(headers: Headers): RateLimitInfo {\n const info: RateLimitInfo = {};\n\n const retryAfter = headers.get(\"Retry-After\");\n if (retryAfter) {\n const seconds = parseInt(retryAfter, 10);\n if (!isNaN(seconds)) {\n info.retryAfter = seconds;\n }\n }\n\n const limit = headers.get(\"X-RateLimit-Limit\");\n if (limit) {\n const parsed = parseInt(limit, 10);\n if (!isNaN(parsed)) {\n info.limit = parsed;\n }\n }\n\n const remaining = headers.get(\"X-RateLimit-Remaining\");\n if (remaining) {\n const parsed = parseInt(remaining, 10);\n if (!isNaN(parsed)) {\n info.remaining = parsed;\n }\n }\n\n const reset = headers.get(\"X-RateLimit-Reset\");\n if (reset) {\n const timestamp = parseInt(reset, 10);\n if (!isNaN(timestamp)) {\n info.reset = new Date(timestamp * 1000);\n }\n }\n\n const scope = headers.get(\"X-RateLimit-Scope\");\n if (scope) {\n info.scope = scope.trim();\n }\n\n return info;\n}\n\n/** Cap a raw (non-JSON) error body so a stray HTML page can't become a huge message. */\nconst MAX_RAW_ERROR_BODY_CHARS = 500;\n\n/**\n * Parse an error response body.\n *\n * Reads the body once as text, then:\n * - if it parses as a JSON object, extracts `{code, message}` (falling back to\n * the `error` field when `message` is absent);\n * - otherwise (plain-text/HTML body, or malformed JSON) preserves the raw body\n * text as the message so a server's human-readable error — e.g. a proxy's\n * `502 Bad Gateway` page — is not silently discarded.\n */\nasync function parseErrorBody(\n response: Response,\n): Promise<ApiErrorBody | null> {\n const contentType = response.headers.get(\"Content-Type\") || \"\";\n\n let raw: string;\n try {\n raw = await response.text();\n } catch {\n return null;\n }\n\n if (contentType.includes(\"application/json\")) {\n try {\n const body = JSON.parse(raw) as Record<string, unknown>;\n if (typeof body === \"object\" && body !== null) {\n // Error bodies come in two shapes: {code, message} or {error, code, details}.\n // Fall back to `error` when `message` is absent so the server's\n // human-readable message is not lost.\n const message =\n ((body.message as string) ?? (body.error as string)) ||\n response.statusText;\n return {\n code: (body.code as string) || \"UNKNOWN_ERROR\",\n message,\n details: body.details as Record<string, unknown> | undefined,\n };\n }\n } catch {\n // Content-Type claimed JSON but the body did not parse — fall through and\n // preserve the raw text below instead of throwing it away.\n }\n }\n\n // Non-JSON body (or unparseable JSON): keep the raw text as the message.\n const trimmed = raw.trim();\n if (trimmed) {\n const message =\n trimmed.length > MAX_RAW_ERROR_BODY_CHARS\n ? `${trimmed.slice(0, MAX_RAW_ERROR_BODY_CHARS)}…`\n : trimmed;\n return { code: \"UNKNOWN_ERROR\", message };\n }\n\n return null;\n}\n\n/**\n * Create an appropriate error from an HTTP response\n */\nexport async function createErrorFromResponse(\n response: Response,\n): Promise<SpooledError> {\n const requestId = response.headers.get(\"X-Request-ID\") ?? undefined;\n const body = await parseErrorBody(response);\n\n const message =\n body?.message || response.statusText || `HTTP ${response.status}`;\n const code = body?.code || \"UNKNOWN_ERROR\";\n const details = body?.details;\n\n switch (response.status) {\n case 400:\n return new ValidationError(message, code, details, requestId);\n\n // A missing or mistyped JSON field is a 422 from the API's extractor; it is\n // the same class of caller error as a 400 field-rule failure.\n case 422:\n return new ValidationError(message, code, details, requestId, 422);\n\n case 401:\n return new AuthenticationError(message, code, details, requestId);\n\n case 403:\n return new AuthorizationError(message, code, details, requestId);\n\n case 404:\n return new NotFoundError(message, code, details, requestId);\n\n case 409:\n return new ConflictError(message, code, details, requestId);\n\n case 413:\n return new PayloadTooLargeError(message, code, details, requestId);\n\n case 429: {\n const rateLimitInfo = parseRateLimitHeaders(response.headers);\n return new RateLimitError(\n message,\n code,\n rateLimitInfo,\n details,\n requestId,\n );\n }\n\n default:\n if (response.status >= 500) {\n return new ServerError(\n message,\n response.status,\n code,\n details,\n requestId,\n );\n }\n return new SpooledError(\n message,\n response.status,\n code,\n details,\n requestId,\n );\n }\n}\n\n/**\n * Check if an error is a SpooledError instance\n */\nexport function isSpooledError(error: unknown): error is SpooledError {\n return error instanceof SpooledError;\n}\n\n/**\n * Check if an error is retryable\n */\nexport function isRetryableError(error: unknown): boolean {\n if (error instanceof SpooledError) {\n return error.isRetryable();\n }\n // Network errors from fetch are typically retryable\n if (error instanceof TypeError) {\n return true;\n }\n return false;\n}\n","/**\n * Case Conversion Utilities\n *\n * Provides deep conversion between snake_case (API) and camelCase (SDK).\n * User-defined JSON blobs are preserved without conversion.\n */\n\n/**\n * Keys that should NOT have their values deeply converted.\n * These typically contain user-defined JSON that shouldn't be modified.\n */\nconst SKIP_CONVERSION_KEYS = new Set([\n \"payload\",\n \"result\",\n \"metadata\",\n \"tags\",\n \"settings\",\n \"details\",\n \"extra\",\n \"payloadTemplate\",\n \"payload_template\",\n \"customLimits\",\n \"custom_limits\",\n]);\n\n/**\n * Check if a value is a plain object (not array, Date, null, etc.)\n */\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n !(value instanceof Date) &&\n !(value instanceof RegExp) &&\n Object.prototype.toString.call(value) === \"[object Object]\"\n );\n}\n\n/**\n * Convert a string from camelCase to snake_case\n */\nexport function camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * Convert a string from snake_case to camelCase\n */\nexport function snakeToCamel(str: string): string {\n // Handle numeric segments like `completed_24h` -> `completed24h`\n // and then standard `_x` -> `X` conversion.\n return str\n .replace(/_([0-9]+)/g, (_, digits) => digits)\n .replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n}\n\n/**\n * Deep convert object keys from camelCase to snake_case.\n * Preserves values in SKIP_CONVERSION_KEYS without deep conversion.\n *\n * @param obj - Object to convert\n * @param skipDeepConversion - Whether current context should skip deep conversion of values\n * @returns Object with snake_case keys\n */\nexport function toSnakeCase<T = unknown>(\n obj: T,\n skipDeepConversion = false,\n): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => toSnakeCase(item, skipDeepConversion)) as T;\n }\n\n if (obj instanceof Date) {\n return obj.toISOString() as T;\n }\n\n if (!isPlainObject(obj)) {\n return obj;\n }\n\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const snakeKey = camelToSnake(key);\n\n // Check if this key's value should skip deep conversion\n const shouldSkip =\n skipDeepConversion ||\n SKIP_CONVERSION_KEYS.has(key) ||\n SKIP_CONVERSION_KEYS.has(snakeKey);\n\n if (shouldSkip) {\n // Don't convert the value, just preserve it as-is\n result[snakeKey] = value;\n } else {\n // Recursively convert the value\n result[snakeKey] = toSnakeCase(value, false);\n }\n }\n\n return result as T;\n}\n\n/**\n * Deep convert object keys from snake_case to camelCase.\n * Preserves values in SKIP_CONVERSION_KEYS without deep conversion.\n *\n * @param obj - Object to convert\n * @param skipDeepConversion - Whether current context should skip deep conversion of values\n * @returns Object with camelCase keys\n */\nexport function toCamelCase<T = unknown>(\n obj: T,\n skipDeepConversion = false,\n): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => toCamelCase(item, skipDeepConversion)) as T;\n }\n\n if (obj instanceof Date) {\n return obj as T;\n }\n\n if (!isPlainObject(obj)) {\n return obj;\n }\n\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const camelKey = snakeToCamel(key);\n\n // Check if this key's value should skip deep conversion\n const shouldSkip =\n skipDeepConversion ||\n SKIP_CONVERSION_KEYS.has(key) ||\n SKIP_CONVERSION_KEYS.has(camelKey);\n\n if (shouldSkip) {\n // Don't convert the value, just preserve it as-is\n result[camelKey] = value;\n } else {\n // Recursively convert the value\n result[camelKey] = toCamelCase(value, false);\n }\n }\n\n return result as T;\n}\n\n/**\n * Convert request body from camelCase (SDK) to snake_case (API)\n */\nexport function convertRequest<T>(body: T): T {\n return toSnakeCase(body);\n}\n\n/**\n * Convert response body from snake_case (API) to camelCase (SDK)\n */\nexport function convertResponse<T>(body: T): T {\n return toCamelCase(body);\n}\n\n/**\n * Convert query parameters from camelCase to snake_case.\n * Only converts top-level keys, not nested objects.\n */\nexport function convertQueryParams(\n params: Record<string, string | number | boolean | undefined>,\n): Record<string, string> {\n const result: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n const snakeKey = camelToSnake(key);\n result[snakeKey] = String(value);\n }\n }\n\n return result;\n}\n","/**\n * Retry Utility\n *\n * Implements exponential backoff with jitter for retrying failed requests.\n */\n\nimport type { RetryConfig } from \"../config.js\";\nimport { RateLimitError, isRetryableError } from \"../errors.js\";\n\n/** Options for a single retry operation */\nexport interface RetryOptions {\n /** Retry configuration */\n config: RetryConfig;\n /** Optional abort signal to cancel retries */\n signal?: AbortSignal;\n /** Callback for retry events (for logging/debugging) */\n onRetry?: (attempt: number, error: Error, delayMs: number) => void;\n}\n\n/**\n * Calculate delay for a given attempt using exponential backoff with optional jitter\n *\n * @param attempt - Current attempt number (1-based)\n * @param config - Retry configuration\n * @param retryAfterSeconds - Optional Retry-After header value\n * @returns Delay in milliseconds\n */\nexport function calculateDelay(\n attempt: number,\n config: RetryConfig,\n retryAfterSeconds?: number,\n): number {\n // If we have a Retry-After value, use it (but respect maxDelay)\n if (retryAfterSeconds !== undefined && retryAfterSeconds > 0) {\n const retryAfterMs = retryAfterSeconds * 1000;\n return Math.min(retryAfterMs, config.maxDelay);\n }\n\n // Calculate exponential delay: baseDelay * factor^(attempt-1)\n const exponentialDelay =\n config.baseDelay * Math.pow(config.factor, attempt - 1);\n\n // Cap at maxDelay\n let delay = Math.min(exponentialDelay, config.maxDelay);\n\n // Add jitter if enabled (random value between 0 and 25% of delay)\n if (config.jitter) {\n const jitterRange = delay * 0.25;\n const jitter = Math.random() * jitterRange;\n delay = delay + jitter;\n }\n\n return Math.floor(delay);\n}\n\n/**\n * Check if an error should be retried\n *\n * @param error - The error to check\n * @param attempt - Current attempt number\n * @param config - Retry configuration\n * @returns Whether the error is retryable\n */\nexport function shouldRetry(\n error: Error,\n attempt: number,\n config: RetryConfig,\n): boolean {\n // Don't retry if we've exhausted attempts\n // attempt is 1-based, so with maxRetries=2, we allow attempts 1, 2, 3 (initial + 2 retries)\n if (attempt > config.maxRetries) {\n return false;\n }\n\n // Use custom retry function if provided\n if (config.retryOn) {\n return config.retryOn(error, attempt);\n }\n\n // Default: retry on retryable errors\n return isRetryableError(error);\n}\n\n/**\n * Sleep for the specified duration\n *\n * @param ms - Duration in milliseconds\n * @param signal - Optional abort signal\n * @returns Promise that resolves after the delay or rejects if aborted\n */\nexport function sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n return;\n }\n\n const timeoutId = setTimeout(() => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n\n const onAbort = () => {\n clearTimeout(timeoutId);\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n };\n\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\n/**\n * Execute a function with retry logic\n *\n * @param fn - Async function to execute\n * @param options - Retry options\n * @returns Promise resolving to the function result\n * @throws Last error if all retries fail\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: RetryOptions,\n): Promise<T> {\n const { config, signal, onRetry } = options;\n let lastError: Error | undefined;\n\n for (let attempt = 1; attempt <= config.maxRetries + 1; attempt++) {\n // Check if aborted before each attempt\n if (signal?.aborted) {\n throw new DOMException(\"Aborted\", \"AbortError\");\n }\n\n try {\n return await fn();\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n lastError = err;\n\n // Check if we should retry\n if (!shouldRetry(err, attempt, config)) {\n throw err;\n }\n\n // Calculate delay\n let retryAfter: number | undefined;\n if (err instanceof RateLimitError) {\n retryAfter = err.getRetryAfter();\n }\n const delayMs = calculateDelay(attempt, config, retryAfter);\n\n // Notify about retry\n onRetry?.(attempt, err, delayMs);\n\n // Wait before retrying\n await sleep(delayMs, signal);\n }\n }\n\n // Should not reach here, but throw last error just in case\n throw lastError ?? new Error(\"Retry failed with unknown error\");\n}\n\n/**\n * Create a retry wrapper with pre-configured options\n *\n * @param config - Retry configuration\n * @returns Function to wrap async operations with retry logic\n */\nexport function createRetryWrapper(config: RetryConfig) {\n return function retry<T>(\n fn: () => Promise<T>,\n options?: Partial<Omit<RetryOptions, \"config\">>,\n ): Promise<T> {\n return withRetry(fn, {\n config,\n ...options,\n });\n };\n}\n","/**\n * HTTP Client Utility\n *\n * Provides a fetch wrapper with:\n * - URL building and query string encoding\n * - JSON request/response handling\n * - Timeout support via AbortController\n * - Automatic retry with exponential backoff\n * - Circuit breaker protection\n * - Case conversion (camelCase <-> snake_case)\n */\n\nimport type { ResolvedConfig, DebugFn } from \"../config.js\";\nimport { API_BASE_PATH } from \"../config.js\";\nimport type { RetryConfig } from \"../config.js\";\nimport {\n createErrorFromResponse,\n NetworkError,\n parseRateLimitHeaders,\n RateLimitError,\n TimeoutError,\n SpooledError,\n type RateLimitInfo,\n} from \"../errors.js\";\nimport {\n convertRequest,\n convertResponse,\n convertQueryParams,\n} from \"./casing.js\";\nimport { withRetry } from \"./retry.js\";\nimport { CircuitBreaker } from \"./circuit-breaker.js\";\n\n/**\n * HTTP methods considered idempotent per HTTP semantics.\n * Automatic retry on ambiguous failures (network/timeout/5xx) is only safe\n * for these; non-idempotent methods (POST/PATCH) may cause duplicate side\n * effects if retried after the request already reached the server.\n */\nconst IDEMPOTENT_METHODS = new Set<HttpMethod>([\"GET\", \"PUT\", \"DELETE\"]);\n\n/** HTTP methods */\nexport type HttpMethod = \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n\n/** Query parameters type */\nexport type QueryParams = Record<string, string | number | boolean | undefined>;\n\n/** Request options for HTTP client */\nexport interface HttpRequestOptions {\n /** HTTP method (default: GET) */\n method?: HttpMethod;\n /** Request body (will be JSON stringified) */\n body?: unknown;\n /**\n * Raw request body (sent as-is, not JSON stringified).\n * Use this for endpoints that require an exact byte payload (e.g. webhook signature verification).\n */\n rawBody?: string | Uint8Array | ArrayBuffer;\n /** Query parameters */\n params?: QueryParams;\n /**\n * Skip automatically prefixing the path with `/api/v1`.\n * Use this for top-level endpoints like `/health` or `/metrics`.\n */\n skipApiPrefix?: boolean;\n /** Additional headers */\n headers?: Record<string, string>;\n /** Request timeout in milliseconds (overrides client default) */\n timeout?: number;\n /** Whether to skip case conversion for request body */\n skipRequestConversion?: boolean;\n /** Whether to skip case conversion for response body */\n skipResponseConversion?: boolean;\n /** Whether to skip retry logic */\n skipRetry?: boolean;\n /**\n * The request is safe to replay even though it is a POST/PATCH, so network\n * errors, timeouts, 5xx and 408 are retried like they are for a GET.\n *\n * Use it only for calls the server makes idempotent: lease-fenced job and\n * worker acks (complete/fail/heartbeat answer a replay with 409) and job\n * creation with an idempotency key (the server returns the existing job).\n */\n idempotent?: boolean;\n /**\n * Never try to refresh the access token when this request gets a 401.\n * Set on the auth calls that the refresh itself makes.\n */\n skipAuthRefresh?: boolean;\n /** Optional abort signal */\n signal?: AbortSignal;\n}\n\n/** HTTP response wrapper */\nexport interface HttpResponse<T> {\n /** Response status code */\n status: number;\n /** Response headers */\n headers: Headers;\n /** Parsed response body */\n data: T;\n}\n\n/**\n * HTTP Client class\n *\n * Handles all HTTP communication with the Spooled API.\n */\nexport class HttpClient {\n private readonly config: ResolvedConfig;\n private readonly circuitBreaker: CircuitBreaker;\n private readonly debug: DebugFn | null;\n\n /** Current authentication token (API key or JWT) */\n private authToken: string | undefined;\n\n /** Optional function to mint a fresh access token (set when auto-refresh is enabled) */\n private refreshTokenFn: (() => Promise<string>) | null = null;\n\n /**\n * The refresh currently in flight, shared by every request that gets a 401\n * meanwhile. A boolean guard here made the second concurrent 401 skip the\n * refresh and fail even though the token was about to be replaced.\n */\n private refreshInFlight: Promise<boolean> | null = null;\n\n /** Rate-limit headers of the most recent response that carried them */\n private lastRateLimit: RateLimitInfo | undefined;\n\n constructor(config: ResolvedConfig, circuitBreaker: CircuitBreaker) {\n this.config = config;\n this.circuitBreaker = circuitBreaker;\n this.debug = config.debug;\n\n // Set initial auth token\n this.authToken = config.accessToken ?? config.apiKey;\n }\n\n /**\n * Set the authentication token\n */\n setAuthToken(token: string): void {\n this.authToken = token;\n }\n\n /**\n * The `X-RateLimit-*` (and `Retry-After`) values of the most recent\n * response that carried them, successful or not. `undefined` until such a\n * response arrives. With concurrent requests it is the last one to finish.\n */\n getLastRateLimitInfo(): RateLimitInfo | undefined {\n return this.lastRateLimit ? { ...this.lastRateLimit } : undefined;\n }\n\n /**\n * Set the token refresh function.\n *\n * When set, an expired-token 401 on the data plane triggers a single\n * refresh + retry of the original request with the new token.\n */\n setRefreshTokenFn(fn: () => Promise<string>): void {\n this.refreshTokenFn = fn;\n }\n\n /**\n * Refresh the access token once for all callers.\n *\n * Resolves true when a new token is installed, false when the refresh failed\n * (the caller then surfaces its original 401).\n */\n private refreshAuthToken(): Promise<boolean> {\n if (!this.refreshInFlight) {\n const refresh = this.refreshTokenFn!;\n this.refreshInFlight = (async () => {\n try {\n this.setAuthToken(await refresh());\n return true;\n } catch (refreshError) {\n const message =\n refreshError instanceof Error ? refreshError.message : \"unknown\";\n this.debug?.(\"Token refresh failed\", { error: message });\n return false;\n } finally {\n this.refreshInFlight = null;\n }\n })();\n }\n return this.refreshInFlight;\n }\n\n /**\n * Build full URL with query parameters\n */\n private buildUrl(\n path: string,\n params?: Record<string, string | number | boolean | undefined>,\n skipApiPrefix?: boolean,\n ): string {\n // Ensure path starts with /api/v1 unless explicitly skipped\n const fullPath = skipApiPrefix\n ? path\n : path.startsWith(\"/api/\")\n ? path\n : `${API_BASE_PATH}${path}`;\n const url = new URL(fullPath, this.config.baseUrl);\n\n if (params) {\n const convertedParams = convertQueryParams(params);\n for (const [key, value] of Object.entries(convertedParams)) {\n url.searchParams.append(key, value);\n }\n }\n\n return url.toString();\n }\n\n /**\n * Build request headers\n */\n private buildHeaders(customHeaders?: Record<string, string>): Headers {\n const headers = new Headers();\n\n // Add default headers\n for (const [key, value] of Object.entries(this.config.headers)) {\n headers.set(key, value);\n }\n\n // Add user agent\n headers.set(\"User-Agent\", this.config.userAgent);\n\n // Add auth token if available\n if (this.authToken) {\n headers.set(\"Authorization\", `Bearer ${this.authToken}`);\n }\n\n // Add custom headers\n if (customHeaders) {\n for (const [key, value] of Object.entries(customHeaders)) {\n headers.set(key, value);\n }\n }\n\n return headers;\n }\n\n /**\n * Execute a fetch request with timeout\n */\n private async fetchWithTimeout(\n url: string,\n init: RequestInit,\n timeoutMs: number,\n externalSignal?: AbortSignal,\n ): Promise<Response> {\n const controller = new AbortController();\n const { signal } = controller;\n\n // Link external signal to our controller\n if (externalSignal) {\n if (externalSignal.aborted) {\n controller.abort();\n } else {\n externalSignal.addEventListener(\"abort\", () => controller.abort(), {\n once: true,\n });\n }\n }\n\n // Set up timeout\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const response = await this.config.fetch(url, {\n ...init,\n signal,\n });\n return response;\n } catch (error) {\n if (error instanceof DOMException && error.name === \"AbortError\") {\n // Check if this was a timeout or user abort\n if (externalSignal?.aborted) {\n throw error; // User aborted\n }\n throw new TimeoutError(\n `Request timed out after ${timeoutMs}ms`,\n timeoutMs,\n );\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Execute a single HTTP request (no retry)\n */\n private async executeRequest<T>(\n url: string,\n options: HttpRequestOptions,\n hasRefreshed = false,\n ): Promise<HttpResponse<T>> {\n const method = options.method ?? \"GET\";\n // The token this attempt is sent with; a 401 for an older token than the\n // current one only needs a replay, not another refresh.\n const tokenUsed = this.authToken;\n const headers = this.buildHeaders(options.headers);\n const timeout = options.timeout ?? this.config.timeout;\n\n // Build request init\n const init: RequestInit = {\n method,\n headers,\n };\n\n // Add body for methods that support it\n if (method !== \"GET\") {\n if (options.rawBody !== undefined) {\n init.body = options.rawBody as unknown as RequestInit[\"body\"];\n } else if (options.body !== undefined) {\n const body = options.skipRequestConversion\n ? options.body\n : convertRequest(options.body);\n init.body = JSON.stringify(body);\n }\n }\n\n // The default `Content-Type: application/json` is only true when there is a\n // body. An empty body that claims to be JSON makes the API's optional-body\n // extractors (e.g. POST /queues/{name}/pause) fail with \"EOF while parsing\".\n if (init.body === undefined) {\n headers.delete(\"Content-Type\");\n }\n\n this.debug?.(`${method} ${url}`, { timeout, hasBody: !!options.body });\n\n let response: Response;\n try {\n response = await this.fetchWithTimeout(\n url,\n init,\n timeout,\n options.signal,\n );\n } catch (error) {\n if (error instanceof TimeoutError || error instanceof SpooledError) {\n throw error;\n }\n // Network error (fetch failed to get a response)\n const cause = error instanceof Error ? error : undefined;\n throw new NetworkError(\n `Network request failed: ${cause?.message ?? \"Unknown error\"}`,\n cause,\n );\n }\n\n this.debug?.(`Response: ${response.status}`, { url });\n\n this.recordRateLimit(response.headers);\n\n // Handle non-OK responses\n if (!response.ok) {\n // On an expired-token 401, refresh the access token (once, shared by\n // every concurrent request) and replay the original request. Replays are\n // limited to one per request, and the auth calls the refresh itself makes\n // are exempt, so a genuinely invalid credential can't loop.\n if (\n response.status === 401 &&\n this.refreshTokenFn &&\n !hasRefreshed &&\n !options.skipAuthRefresh\n ) {\n const alreadyRefreshed = this.authToken !== tokenUsed;\n if (alreadyRefreshed || (await this.refreshAuthToken())) {\n return this.executeRequest<T>(url, options, true);\n }\n }\n\n const apiError = await createErrorFromResponse(response);\n throw apiError;\n }\n\n // Parse response body\n let data: T;\n const contentType = response.headers.get(\"Content-Type\") || \"\";\n\n if (response.status === 204) {\n data = undefined as T;\n } else if (contentType.includes(\"application/json\")) {\n const rawData = (await response.json()) as T;\n data = options.skipResponseConversion\n ? rawData\n : convertResponse(rawData);\n } else {\n // Non-JSON response (e.g. Prometheus metrics text)\n data = (await response.text()) as unknown as T;\n }\n\n return {\n status: response.status,\n headers: response.headers,\n data,\n };\n }\n\n /** Remember the rate-limit headers of a response that has them. */\n private recordRateLimit(headers: Headers | undefined): void {\n if (\n !headers ||\n typeof headers.get !== \"function\" ||\n (headers.get(\"X-RateLimit-Limit\") === null &&\n headers.get(\"X-RateLimit-Remaining\") === null)\n ) {\n return;\n }\n this.lastRateLimit = parseRateLimitHeaders(headers);\n }\n\n /**\n * Make an HTTP request with retry and circuit breaker\n */\n async request<T>(\n path: string,\n options: HttpRequestOptions = {},\n ): Promise<HttpResponse<T>> {\n const url = this.buildUrl(path, options.params, options.skipApiPrefix);\n const method = options.method ?? \"GET\";\n\n // Wrap in circuit breaker\n const execute = async (): Promise<HttpResponse<T>> => {\n return this.circuitBreaker.execute(() =>\n this.executeRequest<T>(url, options),\n );\n };\n\n // Apply retry logic if not skipped\n if (options.skipRetry) {\n return execute();\n }\n\n return withRetry(execute, {\n config: this.resolveRetryConfig(method, options),\n signal: options.signal,\n onRetry: (attempt, error, delayMs) => {\n this.debug?.(`Retry attempt ${attempt} after ${delayMs}ms`, {\n error: error.message,\n });\n },\n });\n }\n\n /**\n * Determine whether a request carries an idempotency key (making a\n * non-idempotent method safe to retry).\n */\n private hasIdempotencyKey(options: HttpRequestOptions): boolean {\n if (!options.headers) {\n return false;\n }\n return Object.keys(options.headers).some(\n (key) => key.toLowerCase() === \"idempotency-key\",\n );\n }\n\n /**\n * Resolve the retry configuration for a request.\n *\n * Idempotent methods (GET/PUT/DELETE), any request carrying an idempotency\n * key and any request marked `idempotent` retry normally. Non-idempotent\n * methods (POST/PATCH) otherwise must NOT be retried on ambiguous failures\n * (network/timeout/5xx) — doing so risks duplicate jobs, double claims,\n * etc. They are still retried on a rate-limit 429, which is rejected before\n * the server processes the request and is therefore side-effect-free. A\n * quota 429 is never retried: it does not clear for hours.\n */\n private resolveRetryConfig(\n method: HttpMethod,\n options: HttpRequestOptions,\n ): RetryConfig {\n const base = this.config.retry;\n\n if (\n options.idempotent ||\n IDEMPOTENT_METHODS.has(method) ||\n this.hasIdempotencyKey(options)\n ) {\n return base;\n }\n\n return {\n ...base,\n retryOn: (error, attempt) => {\n if (error instanceof RateLimitError) {\n if (error.isQuota) {\n return false;\n }\n return base.retryOn ? base.retryOn(error, attempt) : true;\n }\n return false;\n },\n };\n }\n\n /**\n * Make a GET request\n */\n async get<T>(\n path: string,\n options?: Omit<HttpRequestOptions, \"method\" | \"body\">,\n ): Promise<T> {\n const response = await this.request<T>(path, { ...options, method: \"GET\" });\n return response.data;\n }\n\n /**\n * Make a POST request\n */\n async post<T>(\n path: string,\n body?: unknown,\n options?: Omit<HttpRequestOptions, \"method\" | \"body\">,\n ): Promise<T> {\n const response = await this.request<T>(path, {\n ...options,\n method: \"POST\",\n body,\n });\n return response.data;\n }\n\n /**\n * Make a PUT request\n */\n async put<T>(\n path: string,\n body?: unknown,\n options?: Omit<HttpRequestOptions, \"method\" | \"body\">,\n ): Promise<T> {\n const response = await this.request<T>(path, {\n ...options,\n method: \"PUT\",\n body,\n });\n return response.data;\n }\n\n /**\n * Make a PATCH request\n */\n async patch<T>(\n path: string,\n body?: unknown,\n options?: Omit<HttpRequestOptions, \"method\" | \"body\">,\n ): Promise<T> {\n const response = await this.request<T>(path, {\n ...options,\n method: \"PATCH\",\n body,\n });\n return response.data;\n }\n\n /**\n * Make a DELETE request\n */\n async delete<T = void>(\n path: string,\n options?: Omit<HttpRequestOptions, \"method\" | \"body\">,\n ): Promise<T> {\n const response = await this.request<T>(path, {\n ...options,\n method: \"DELETE\",\n });\n return response.data;\n }\n}\n\n/**\n * Create an HTTP client instance\n */\nexport function createHttpClient(\n config: ResolvedConfig,\n circuitBreaker: CircuitBreaker,\n): HttpClient {\n return new HttpClient(config, circuitBreaker);\n}\n","/**\n * Circuit Breaker Utility\n *\n * Implements the circuit breaker pattern to prevent cascading failures.\n * States: CLOSED (normal) -> OPEN (failing) -> HALF_OPEN (testing) -> CLOSED\n */\n\nimport type { CircuitBreakerConfig } from \"../config.js\";\nimport {\n CircuitBreakerOpenError,\n RateLimitError,\n isRetryableError,\n} from \"../errors.js\";\n\n/** Circuit breaker states */\nexport enum CircuitState {\n /** Normal operation - requests flow through */\n CLOSED = \"CLOSED\",\n /** Circuit is open - requests are rejected immediately */\n OPEN = \"OPEN\",\n /** Testing state - limited requests allowed to test recovery */\n HALF_OPEN = \"HALF_OPEN\",\n}\n\n/** Circuit breaker state change event */\nexport interface CircuitStateChange {\n from: CircuitState;\n to: CircuitState;\n timestamp: Date;\n failureCount: number;\n}\n\n/** Circuit breaker options */\nexport interface CircuitBreakerOptions extends CircuitBreakerConfig {\n /** Callback when state changes */\n onStateChange?: (event: CircuitStateChange) => void;\n /**\n * Custom function to determine if an error should count as a failure.\n * Defaults to {@link isCircuitBreakerFailure}.\n */\n isFailure?: (error: Error) => boolean;\n}\n\n/**\n * Default circuit breaker failure predicate.\n *\n * Counts the errors that say the API or the network is unhealthy: the\n * retryable ones (network errors, timeouts, 5xx, 408). A 429 never counts. A\n * rate-limit 429 is the API working as designed and telling this client to\n * slow down for `Retry-After` seconds; counting it let a burst above the plan\n * limit open the breaker and fail every call on the client for the breaker\n * timeout (30 s by default), including the retries that `Retry-After` had\n * already scheduled. The retry layer handles rate limiting on its own. A quota\n * 429 (`RateLimitError.isQuota`) was already excluded.\n */\nexport function isCircuitBreakerFailure(error: Error): boolean {\n if (error instanceof RateLimitError) {\n return false;\n }\n return isRetryableError(error);\n}\n\n/**\n * Circuit Breaker implementation\n *\n * Tracks failures and prevents requests when the failure threshold is reached.\n */\nexport class CircuitBreaker {\n private state: CircuitState = CircuitState.CLOSED;\n private failureCount = 0;\n private successCount = 0;\n private lastFailureTime: number = 0;\n private readonly config: CircuitBreakerOptions;\n\n constructor(config: CircuitBreakerOptions) {\n this.config = config;\n }\n\n /**\n * Get current circuit state\n */\n getState(): CircuitState {\n // Check if we should transition from OPEN to HALF_OPEN\n if (this.state === CircuitState.OPEN) {\n const now = Date.now();\n if (now - this.lastFailureTime >= this.config.timeout) {\n this.transitionTo(CircuitState.HALF_OPEN);\n }\n }\n return this.state;\n }\n\n /**\n * Check if circuit breaker is enabled\n */\n isEnabled(): boolean {\n return this.config.enabled;\n }\n\n /**\n * Check if requests are currently allowed\n */\n isAllowed(): boolean {\n if (!this.config.enabled) {\n return true;\n }\n\n const state = this.getState();\n return state === CircuitState.CLOSED || state === CircuitState.HALF_OPEN;\n }\n\n /**\n * Record a successful request\n */\n recordSuccess(): void {\n if (!this.config.enabled) {\n return;\n }\n\n if (this.state === CircuitState.HALF_OPEN) {\n this.successCount++;\n\n if (this.successCount >= this.config.successThreshold) {\n this.transitionTo(CircuitState.CLOSED);\n }\n } else if (this.state === CircuitState.CLOSED) {\n // Reset failure count on success in closed state\n this.failureCount = 0;\n }\n }\n\n /**\n * Record a failed request\n */\n recordFailure(error: Error): void {\n if (!this.config.enabled) {\n return;\n }\n\n // Check if this error should count as a failure. Call a caller predicate\n // as a method of its options, as 1.3.0 did, so one that reads `this` works.\n const shouldCount = this.config.isFailure\n ? this.config.isFailure(error)\n : isCircuitBreakerFailure(error);\n\n if (!shouldCount) {\n return;\n }\n\n this.lastFailureTime = Date.now();\n\n if (this.state === CircuitState.HALF_OPEN) {\n // Any failure in half-open state reopens the circuit\n this.transitionTo(CircuitState.OPEN);\n } else if (this.state === CircuitState.CLOSED) {\n this.failureCount++;\n\n if (this.failureCount >= this.config.failureThreshold) {\n this.transitionTo(CircuitState.OPEN);\n }\n }\n }\n\n /**\n * Transition to a new state\n */\n private transitionTo(newState: CircuitState): void {\n if (this.state === newState) {\n return;\n }\n\n const oldState = this.state;\n this.state = newState;\n\n // Reset counters on state change\n if (newState === CircuitState.CLOSED) {\n this.failureCount = 0;\n this.successCount = 0;\n } else if (newState === CircuitState.HALF_OPEN) {\n this.successCount = 0;\n } else if (newState === CircuitState.OPEN) {\n this.successCount = 0;\n }\n\n // Notify listener\n this.config.onStateChange?.({\n from: oldState,\n to: newState,\n timestamp: new Date(),\n failureCount: this.failureCount,\n });\n }\n\n /**\n * Reset the circuit breaker to closed state\n */\n reset(): void {\n this.state = CircuitState.CLOSED;\n this.failureCount = 0;\n this.successCount = 0;\n this.lastFailureTime = 0;\n }\n\n /**\n * Execute a function with circuit breaker protection\n *\n * @param fn - Async function to execute\n * @returns Promise resolving to the function result\n * @throws CircuitBreakerOpenError if circuit is open\n */\n async execute<T>(fn: () => Promise<T>): Promise<T> {\n if (!this.isAllowed()) {\n throw new CircuitBreakerOpenError(\n `Circuit breaker is open. Will retry after ${this.config.timeout}ms`,\n );\n }\n\n try {\n const result = await fn();\n this.recordSuccess();\n return result;\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.recordFailure(err);\n throw error;\n }\n }\n\n /**\n * Get circuit breaker statistics\n */\n getStats(): {\n state: CircuitState;\n failureCount: number;\n successCount: number;\n lastFailureTime: Date | null;\n config: CircuitBreakerConfig;\n } {\n return {\n state: this.getState(),\n failureCount: this.failureCount,\n successCount: this.successCount,\n lastFailureTime: this.lastFailureTime\n ? new Date(this.lastFailureTime)\n : null,\n config: {\n enabled: this.config.enabled,\n failureThreshold: this.config.failureThreshold,\n successThreshold: this.config.successThreshold,\n timeout: this.config.timeout,\n },\n };\n }\n}\n\n/**\n * Create a circuit breaker instance from configuration.\n *\n * Unless the config carries its own `isFailure`, rate-limit 429s do not count\n * as failures (the constructor defaults to {@link isCircuitBreakerFailure}).\n */\nexport function createCircuitBreaker(\n config: CircuitBreakerOptions,\n): CircuitBreaker {\n return new CircuitBreaker(config);\n}\n\n/**\n * Create a disabled circuit breaker (pass-through)\n */\nexport function createDisabledCircuitBreaker(): CircuitBreaker {\n return new CircuitBreaker({\n enabled: false,\n failureThreshold: 0,\n successThreshold: 0,\n timeout: 0,\n });\n}\n","/**\n * Auth Resource\n *\n * Handles authentication operations.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type {\n LoginParams,\n LoginResponse,\n RefreshTokenParams,\n RefreshTokenResponse,\n CurrentUserResponse,\n ValidateTokenParams,\n ValidateTokenResponse,\n StartEmailLoginResponse,\n CheckEmailResponse,\n} from \"../types/auth.js\";\n\nexport class AuthResource {\n constructor(\n private readonly http: HttpClient,\n /** Optional accessor for the client's current refresh token (used by logout) */\n private readonly getRefreshToken?: () => string | undefined,\n ) {}\n\n /**\n * Exchange API key for JWT tokens\n */\n async login(params: LoginParams): Promise<LoginResponse> {\n return this.http.post<LoginResponse>(\"/auth/login\", params, {\n skipAuthRefresh: true,\n });\n }\n\n /**\n * Refresh access token using refresh token\n */\n async refresh(params: RefreshTokenParams): Promise<RefreshTokenResponse> {\n // The refresh call is what a 401 triggers; a 401 on it must surface, not\n // wait on (or start) another refresh.\n return this.http.post<RefreshTokenResponse>(\"/auth/refresh\", params, {\n skipAuthRefresh: true,\n });\n }\n\n /**\n * Logout and revoke the refresh token server-side.\n *\n * The backend requires the refresh token in the body to invalidate the\n * session. When omitted, the client's current refresh token (if any) is\n * used automatically.\n */\n async logout(refreshToken?: string): Promise<void> {\n const token = refreshToken ?? this.getRefreshToken?.();\n await this.http.post<void>(\n \"/auth/logout\",\n token ? { refreshToken: token } : undefined,\n );\n }\n\n /**\n * Get current user/session info\n */\n async me(): Promise<CurrentUserResponse> {\n return this.http.get<CurrentUserResponse>(\"/auth/me\");\n }\n\n /**\n * Validate a token\n *\n * POST /auth/validate is `{ valid, error?, claims? }`. Claims use `org_id`\n * (camelCased `orgId`), not `organizationId`. Invalid tokens send `error`,\n * not `message`.\n */\n async validate(params: ValidateTokenParams): Promise<ValidateTokenResponse> {\n const raw = await this.http.post<RawValidateTokenResponse>(\n \"/auth/validate\",\n params,\n );\n return mapValidate(raw);\n }\n\n /**\n * Start email-based login flow (sends a 6-digit code)\n */\n async startEmailLogin(email: string): Promise<StartEmailLoginResponse> {\n return this.http.post<StartEmailLoginResponse>(\"/auth/email/start\", {\n email,\n });\n }\n\n /**\n * Check whether an email is registered (GET /auth/check-email)\n */\n async checkEmail(email: string): Promise<CheckEmailResponse> {\n return this.http.get<CheckEmailResponse>(\"/auth/check-email\", {\n params: { email },\n });\n }\n}\n\ninterface RawValidateTokenResponse {\n valid: boolean;\n message?: string;\n error?: string;\n claims?: {\n organizationId?: string;\n orgId?: string;\n apiKeyId?: string;\n queues?: string[];\n exp?: number;\n iat?: number;\n };\n}\n\nfunction mapValidate(raw: RawValidateTokenResponse): ValidateTokenResponse {\n const claims = raw.claims;\n const organizationId = claims?.organizationId ?? claims?.orgId;\n return {\n valid: raw.valid,\n message: raw.message ?? raw.error,\n error: raw.error ?? raw.message,\n claims: claims\n ? {\n organizationId: organizationId ?? \"\",\n orgId: claims.orgId ?? organizationId,\n apiKeyId: claims.apiKeyId ?? \"\",\n queues: claims.queues ?? [],\n exp: claims.exp ?? 0,\n iat: claims.iat ?? 0,\n }\n : undefined,\n };\n}\n","/**\n * Failure message coercion\n *\n * `POST /jobs/{id}/fail` rejects an empty or over-long `error` with a 400.\n * A worker that reported its failure with such text got nothing recorded: the\n * job stayed `processing` until its lease ran out, then ran again. The text of\n * a failure is therefore always made acceptable before it is sent.\n */\n\n/** Longest error text the API accepts (characters, not bytes). */\nexport const MAX_FAILURE_MESSAGE_CHARS = 2048;\n\n/** Text sent when a handler failed without saying why. */\nexport const DEFAULT_FAILURE_MESSAGE = \"Job failed\";\n\n/**\n * Make `message` acceptable to the fail endpoint: empty becomes\n * {@link DEFAULT_FAILURE_MESSAGE}; text over {@link MAX_FAILURE_MESSAGE_CHARS}\n * is cut to that many characters. The cut is by code point, so an emoji or\n * other astral character is never split into a lone surrogate.\n */\nexport function coerceFailureMessage(message: unknown): string {\n const text =\n typeof message === \"string\" ? message : message == null ? \"\" : `${message}`;\n if (text === \"\") {\n return DEFAULT_FAILURE_MESSAGE;\n }\n // UTF-16 length is an upper bound of the code point count: skip the\n // allocation for the common short message.\n if (text.length <= MAX_FAILURE_MESSAGE_CHARS) {\n return text;\n }\n const codePoints = Array.from(text);\n return codePoints.length <= MAX_FAILURE_MESSAGE_CHARS\n ? text\n : codePoints.slice(0, MAX_FAILURE_MESSAGE_CHARS).join(\"\");\n}\n","/**\n * Paging and query helpers shared by the list resources.\n */\n\n/** Response header that says whether another page follows (API 0.1.122+). */\nexport const HAS_MORE_HEADER = \"X-Has-More\";\n\n/**\n * Whether another page follows a list response.\n *\n * Reads `X-Has-More` when the server sends it. An older server does not, so\n * a page as long as the limit the server applied counts as \"maybe more\": the\n * caller asks once more and gets an empty page at the end.\n */\nexport function hasMoreFromHeaders(\n headers: Headers,\n count: number,\n limit: number | undefined,\n defaultLimit: number,\n maxLimit: number,\n): boolean {\n const header = headers.get(HAS_MORE_HEADER);\n if (header !== null) {\n return header.trim().toLowerCase() === \"true\";\n }\n const applied = Math.min(Math.max(limit ?? defaultLimit, 1), maxLimit);\n return count >= applied;\n}\n\n/**\n * A timestamp query parameter: a `Date` becomes an ISO 8601 UTC string\n * (RFC 3339); a string is sent as given.\n */\nexport function toQueryTimestamp(\n value: Date | string | undefined,\n): string | undefined {\n return value instanceof Date ? value.toISOString() : value;\n}\n","/**\n * Jobs Resource\n *\n * Handles job operations including worker processing endpoints.\n */\n\nimport type { HttpClient, QueryParams } from \"../utils/http.js\";\nimport { coerceFailureMessage } from \"../utils/failure.js\";\nimport { hasMoreFromHeaders, toQueryTimestamp } from \"../utils/paging.js\";\nimport type { ListPage } from \"../types/common.js\";\nimport type {\n Job,\n JobSummary,\n JobStats,\n CreateJobParams,\n CreateJobResult,\n JobHistoryEvent,\n JobHistoryParams,\n ListJobsParams,\n BatchJobStatus,\n ClaimJobsParams,\n ClaimJobsResult,\n CompleteJobParams,\n FailJobParams,\n HeartbeatJobParams,\n BoostPriorityResponse,\n BulkEnqueueParams,\n BulkEnqueueResponse,\n ListDlqParams,\n RetryDlqParams,\n RetryDlqResponse,\n PurgeDlqParams,\n PurgeDlqResponse,\n} from \"../types/jobs.js\";\n\n/** Default and largest page of `GET /jobs` and `GET /jobs/dlq`. */\nconst JOB_LIST_DEFAULT_LIMIT = 50;\nconst JOB_LIST_MAX_LIMIT = 100;\n/** Default and largest page of `GET /jobs/{id}/history`. */\nconst JOB_HISTORY_DEFAULT_LIMIT = 100;\nconst JOB_HISTORY_MAX_LIMIT = 500;\n\n/** DLQ operations */\nexport interface DlqOperations {\n /** List jobs in dead-letter queue */\n list(params?: ListDlqParams): Promise<JobSummary[]>;\n /**\n * List one page of the dead-letter queue with `hasMore` from the\n * `X-Has-More` header (API 0.1.122+).\n */\n listPage(params?: ListDlqParams): Promise<ListPage<JobSummary>>;\n /** Retry jobs from DLQ */\n retry(params: RetryDlqParams): Promise<RetryDlqResponse>;\n /** Purge jobs from DLQ */\n purge(params: PurgeDlqParams): Promise<PurgeDlqResponse>;\n}\n\nexport class JobsResource {\n /** Dead-letter queue operations */\n readonly dlq: DlqOperations;\n\n constructor(private readonly http: HttpClient) {\n this.dlq = {\n list: this.listDlq.bind(this),\n listPage: this.listDlqPage.bind(this),\n retry: this.retryDlq.bind(this),\n purge: this.purgeDlq.bind(this),\n };\n }\n\n /**\n * Create a new job\n */\n async create(params: CreateJobParams): Promise<CreateJobResult> {\n // With an idempotency key the server returns the existing job for a replay\n // (`created: false`), so a network error or 5xx can be retried safely.\n return this.http.post<CreateJobResult>(\"/jobs\", params, {\n idempotent: params.idempotencyKey ? true : undefined,\n });\n }\n\n /**\n * Create a job and return the full job object\n */\n async createAndGet(params: CreateJobParams): Promise<Job> {\n const result = await this.create(params);\n return this.get(result.id);\n }\n\n /**\n * List jobs with optional filtering\n *\n * `status` takes one status or several, and `q`, `jobType`, `createdAfter`\n * and `createdBefore` filter on the server (API 0.1.122+). Use\n * {@link JobsResource.listPage} to also learn whether another page follows.\n */\n async list(params?: ListJobsParams): Promise<JobSummary[]> {\n return (await this.listPage(params)).data;\n }\n\n /**\n * List one page of jobs with `hasMore` from the `X-Has-More` header\n * (API 0.1.122+). Takes the same filters as {@link JobsResource.list}.\n *\n * @example\n * ```typescript\n * let offset = 0;\n * for (;;) {\n * const page = await client.jobs.listPage({\n * status: [\"failed\", \"deadletter\"],\n * createdAfter: new Date(Date.now() - 86_400_000),\n * limit: 100,\n * offset,\n * });\n * handle(page.data);\n * if (!page.hasMore) break;\n * offset += page.data.length;\n * }\n * ```\n */\n async listPage(params?: ListJobsParams): Promise<ListPage<JobSummary>> {\n return this.listSummaries(\"/jobs\", params);\n }\n\n /**\n * Get a job by ID\n */\n async get(id: string): Promise<Job> {\n const job = await this.http.get<Job>(`/jobs/${id}`);\n return withJobType(job);\n }\n\n /**\n * Cancel a pending or scheduled job\n */\n async cancel(id: string): Promise<void> {\n await this.http.delete(`/jobs/${id}`);\n }\n\n /**\n * Retry a failed or dead-lettered job\n */\n async retry(id: string): Promise<Job> {\n const job = await this.http.post<Job>(`/jobs/${id}/retry`);\n return withJobType(job);\n }\n\n /**\n * Boost job priority\n */\n async boostPriority(\n id: string,\n priority: number,\n ): Promise<BoostPriorityResponse> {\n return this.http.put<BoostPriorityResponse>(`/jobs/${id}/priority`, {\n priority,\n });\n }\n\n /**\n * Get the recorded lifecycle events of a job (`GET /jobs/{id}/history`,\n * API 0.1.122+), oldest first unless `order: \"desc\"`.\n *\n * The history is sparse: the server records REST claims (`processing`),\n * completions (`completed`) and failures (`retry_scheduled`,\n * `deadlettered`) and the scheduler's dead-letter sweeps, so a job settled\n * over gRPC may have few or no events. An unknown job is a `NotFoundError`.\n */\n async history(\n id: string,\n params?: JobHistoryParams,\n ): Promise<JobHistoryEvent[]> {\n return (await this.historyPage(id, params)).data;\n }\n\n /**\n * One page of {@link JobsResource.history} with `hasMore` from the\n * `X-Has-More` header. `limit` defaults to 100 (at most 500).\n */\n async historyPage(\n id: string,\n params?: JobHistoryParams,\n ): Promise<ListPage<JobHistoryEvent>> {\n const response = await this.http.request<JobHistoryEvent[]>(\n `/jobs/${id}/history`,\n {\n method: \"GET\",\n params: {\n order: params?.order,\n limit: params?.limit,\n offset: params?.offset,\n },\n },\n );\n const data = response.data ?? [];\n return {\n data,\n hasMore: hasMoreFromHeaders(\n response.headers,\n data.length,\n params?.limit,\n JOB_HISTORY_DEFAULT_LIMIT,\n JOB_HISTORY_MAX_LIMIT,\n ),\n };\n }\n\n /**\n * Get job statistics\n */\n async getStats(): Promise<JobStats> {\n return this.http.get<JobStats>(\"/jobs/stats\");\n }\n\n /**\n * Get status of multiple jobs at once\n */\n async batchStatus(ids: string[]): Promise<BatchJobStatus[]> {\n if (ids.length === 0) {\n return [];\n }\n if (ids.length > 100) {\n throw new Error(\"Maximum 100 job IDs allowed per request\");\n }\n return this.http.get<BatchJobStatus[]>(\"/jobs/status\", {\n params: { ids: ids.join(\",\") },\n });\n }\n\n /**\n * Bulk enqueue multiple jobs\n */\n async bulkEnqueue(params: BulkEnqueueParams): Promise<BulkEnqueueResponse> {\n return this.http.post<BulkEnqueueResponse>(\"/jobs/bulk\", params);\n }\n\n // Worker processing endpoints\n\n /**\n * Claim jobs for worker processing\n */\n async claim(params: ClaimJobsParams): Promise<ClaimJobsResult> {\n return this.http.post<ClaimJobsResult>(\"/jobs/claim\", params);\n }\n\n /**\n * Complete a job (worker ack)\n *\n * Lease-fenced and idempotent on the server, so a network error, timeout or\n * 5xx is retried: a lost ack would otherwise re-run a finished job.\n */\n async complete(\n id: string,\n params: CompleteJobParams,\n ): Promise<{ success: boolean }> {\n return this.http.post<{ success: boolean }>(\n `/jobs/${id}/complete`,\n params,\n { idempotent: true },\n );\n }\n\n /**\n * Fail a job (worker nack)\n *\n * `params.error` is made acceptable first: empty text becomes \"Job failed\"\n * and text over 2048 characters is truncated, because the API rejects both\n * with a 400 that would leave the job processing until its lease expires.\n * Retried like {@link JobsResource.complete}.\n */\n async fail(\n id: string,\n params: FailJobParams,\n ): Promise<{ success: boolean; error?: string }> {\n return this.http.post<{ success: boolean; error?: string }>(\n `/jobs/${id}/fail`,\n { ...params, error: coerceFailureMessage(params.error) },\n { idempotent: true },\n );\n }\n\n /**\n * Extend job lease (heartbeat)\n *\n * Retried like {@link JobsResource.complete}: with the default 30 s lease and\n * 15 s heartbeat, one lost heartbeat leaves no slack.\n */\n async heartbeat(\n id: string,\n params: HeartbeatJobParams,\n ): Promise<{ success: boolean }> {\n return this.http.post<{ success: boolean }>(\n `/jobs/${id}/heartbeat`,\n params,\n { idempotent: true },\n );\n }\n\n // DLQ operations (private implementations)\n\n private async listDlq(params?: ListDlqParams): Promise<JobSummary[]> {\n return (await this.listDlqPage(params)).data;\n }\n\n private async listDlqPage(\n params?: ListDlqParams,\n ): Promise<ListPage<JobSummary>> {\n return this.listSummaries(\"/jobs/dlq\", params);\n }\n\n private async listSummaries(\n path: string,\n params?: ListJobsParams | ListDlqParams,\n ): Promise<ListPage<JobSummary>> {\n const response = await this.http.request<JobSummary[]>(path, {\n method: \"GET\",\n params: jobListQuery(params),\n });\n const rows = response.data ?? [];\n return {\n data: rows.map((row) => ({\n ...row,\n jobType: row.jobType ?? jobTypeFromPayload(row),\n })),\n hasMore: hasMoreFromHeaders(\n response.headers,\n rows.length,\n params?.limit,\n JOB_LIST_DEFAULT_LIMIT,\n JOB_LIST_MAX_LIMIT,\n ),\n };\n }\n\n private async retryDlq(params: RetryDlqParams): Promise<RetryDlqResponse> {\n return this.http.post<RetryDlqResponse>(\"/jobs/dlq/retry\", params);\n }\n\n private async purgeDlq(params: PurgeDlqParams): Promise<PurgeDlqResponse> {\n return this.http.post<PurgeDlqResponse>(\"/jobs/dlq/purge\", params);\n }\n}\n\n/**\n * Query string of a job list: a status list becomes `a,b` and a `Date` an\n * ISO 8601 string (`String(date)` is not RFC 3339 and the API answers 400).\n * Keys the types do not know are passed through as before.\n */\nfunction jobListQuery(\n params?: ListJobsParams | ListDlqParams,\n): QueryParams | undefined {\n if (!params) {\n return undefined;\n }\n const { status, createdAfter, createdBefore, ...rest } =\n params as ListJobsParams;\n let statusParam: string | undefined;\n if (typeof status === \"string\") {\n statusParam = status;\n } else if (status && status.length > 0) {\n statusParam = status.join(\",\");\n }\n return {\n ...(rest as QueryParams),\n status: statusParam,\n createdAfter: toQueryTimestamp(createdAfter),\n createdBefore: toQueryTimestamp(createdBefore),\n };\n}\n\nfunction withJobType<T extends { jobType?: string; payload?: unknown }>(\n job: T,\n): T {\n return {\n ...job,\n jobType: job.jobType ?? jobTypeFromPayload(job) ?? undefined,\n };\n}\n\nfunction jobTypeFromPayload(row: {\n jobType?: string;\n payload?: unknown;\n}): string | undefined {\n if (typeof row.jobType === \"string\" && row.jobType !== \"\") {\n return row.jobType;\n }\n const payload = row.payload;\n if (!payload || typeof payload !== \"object\" || Array.isArray(payload)) {\n return undefined;\n }\n const rec = payload as { jobType?: unknown; job_type?: unknown };\n for (const value of [rec.jobType, rec.job_type]) {\n if (typeof value === \"string\" && value !== \"\") {\n return value;\n }\n }\n return undefined;\n}\n","/**\n * Queues Resource\n *\n * Handles queue configuration and control operations.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type {\n QueueConfig,\n QueueConfigSummary,\n QueueStats,\n UpdateQueueConfigParams,\n PauseQueueResponse,\n ResumeQueueResponse,\n DeleteQueueOptions,\n} from \"../types/queues.js\";\n\nexport class QueuesResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all queues\n */\n async list(): Promise<QueueConfigSummary[]> {\n return this.http.get<QueueConfigSummary[]>(\"/queues\");\n }\n\n /**\n * Get queue configuration by name\n */\n async get(name: string): Promise<QueueConfig> {\n return this.http.get<QueueConfig>(`/queues/${encodeURIComponent(name)}`);\n }\n\n /**\n * Update queue configuration\n */\n async updateConfig(\n name: string,\n params: UpdateQueueConfigParams,\n ): Promise<QueueConfig> {\n return this.http.put<QueueConfig>(\n `/queues/${encodeURIComponent(name)}/config`,\n params,\n );\n }\n\n /**\n * Get queue statistics\n */\n async getStats(name: string): Promise<QueueStats> {\n return this.http.get<QueueStats>(\n `/queues/${encodeURIComponent(name)}/stats`,\n );\n }\n\n /**\n * Pause a queue\n */\n async pause(name: string, reason?: string): Promise<PauseQueueResponse> {\n return this.http.post<PauseQueueResponse>(\n `/queues/${encodeURIComponent(name)}/pause`,\n reason ? { reason } : undefined,\n );\n }\n\n /**\n * Resume a paused queue\n */\n async resume(name: string): Promise<ResumeQueueResponse> {\n return this.http.post<ResumeQueueResponse>(\n `/queues/${encodeURIComponent(name)}/resume`,\n );\n }\n\n /**\n * Delete a queue configuration\n *\n * Without `deleteJobs` the API only deletes an explicit queue config of an\n * idle queue, and answers 409 otherwise: a queue that exists only because\n * jobs were posted to it has no config to delete, and a queue with pending\n * or processing jobs is not idle. Pass `{ deleteJobs: true }` to delete the\n * queue's jobs (and DLQ rows) along with it.\n */\n async delete(name: string, options?: DeleteQueueOptions): Promise<void> {\n await this.http.delete(`/queues/${encodeURIComponent(name)}`, {\n params: options?.deleteJobs ? { deleteJobs: true } : undefined,\n });\n }\n}\n","/**\n * Workers Resource\n *\n * Handles worker registration and management.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type {\n Worker,\n WorkerSummary,\n RegisterWorkerParams,\n RegisterWorkerResponse,\n WorkerHeartbeatParams,\n} from \"../types/workers.js\";\n\nexport class WorkersResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all workers\n */\n async list(): Promise<WorkerSummary[]> {\n return this.http.get<WorkerSummary[]>(\"/workers\");\n }\n\n /**\n * Get a worker by ID\n */\n async get(id: string): Promise<Worker> {\n return this.http.get<Worker>(`/workers/${id}`);\n }\n\n /**\n * Register a new worker\n */\n async register(\n params: RegisterWorkerParams,\n ): Promise<RegisterWorkerResponse> {\n return this.http.post<RegisterWorkerResponse>(\"/workers/register\", params);\n }\n\n /**\n * Send worker heartbeat\n *\n * Idempotent on the server, so network errors, timeouts and 5xx are retried.\n */\n async heartbeat(id: string, params: WorkerHeartbeatParams): Promise<void> {\n await this.http.post(`/workers/${id}/heartbeat`, params, {\n idempotent: true,\n });\n }\n\n /**\n * Deregister a worker\n */\n async deregister(id: string): Promise<void> {\n await this.http.post(`/workers/${id}/deregister`);\n }\n}\n","/**\n * Schedules Resource\n *\n * Handles cron schedule operations.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type {\n Schedule,\n CreateScheduleParams,\n CreateScheduleResponse,\n UpdateScheduleParams,\n ListSchedulesParams,\n TriggerScheduleResponse,\n ScheduleRun,\n} from \"../types/schedules.js\";\n\nexport class SchedulesResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all schedules\n */\n async list(params?: ListSchedulesParams): Promise<Schedule[]> {\n return this.http.get<Schedule[]>(\"/schedules\", {\n params: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * Create a new schedule\n */\n async create(params: CreateScheduleParams): Promise<CreateScheduleResponse> {\n return this.http.post<CreateScheduleResponse>(\"/schedules\", params);\n }\n\n /**\n * Get a schedule by ID\n */\n async get(id: string): Promise<Schedule> {\n return this.http.get<Schedule>(`/schedules/${id}`);\n }\n\n /**\n * Update a schedule\n */\n async update(id: string, params: UpdateScheduleParams): Promise<Schedule> {\n return this.http.put<Schedule>(`/schedules/${id}`, params);\n }\n\n /**\n * Delete a schedule\n */\n async delete(id: string): Promise<void> {\n await this.http.delete(`/schedules/${id}`);\n }\n\n /**\n * Pause a schedule\n */\n async pause(id: string): Promise<Schedule> {\n return this.http.post<Schedule>(`/schedules/${id}/pause`);\n }\n\n /**\n * Resume a paused schedule\n */\n async resume(id: string): Promise<Schedule> {\n return this.http.post<Schedule>(`/schedules/${id}/resume`);\n }\n\n /**\n * Manually trigger a schedule\n */\n async trigger(id: string): Promise<TriggerScheduleResponse> {\n return this.http.post<TriggerScheduleResponse>(`/schedules/${id}/trigger`);\n }\n\n /**\n * Get schedule execution history\n */\n async getHistory(id: string, limit?: number): Promise<ScheduleRun[]> {\n return this.http.get<ScheduleRun[]>(`/schedules/${id}/history`, {\n params: limit ? { limit } : undefined,\n });\n }\n}\n","/**\n * Workflows Resource\n *\n * Handles workflow operations including job dependencies.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport { NotFoundError } from \"../errors.js\";\nimport type { JsonObject } from \"../types/common.js\";\nimport type {\n WorkflowResponse,\n CreateWorkflowParams,\n CreateWorkflowResponse,\n ListWorkflowsParams,\n JobWithDependencies,\n AddDependenciesParams,\n AddDependenciesResponse,\n WorkflowJob,\n WorkflowJobStatus,\n} from \"../types/workflows.js\";\n\n/** Workflow job operations */\nexport interface WorkflowJobOperations {\n /**\n * List all jobs in a workflow.\n *\n * @param workflowId - The workflow ID\n * @example\n * ```typescript\n * const jobs = await client.workflows.jobs.list('wf_123');\n * console.log('Jobs:', jobs.map(j => j.id));\n * ```\n */\n list(workflowId: string): Promise<WorkflowJob[]>;\n\n /**\n * Get a specific job within a workflow.\n *\n * @param workflowId - The workflow ID\n * @param jobId - The job ID\n * @example\n * ```typescript\n * const job = await client.workflows.jobs.get('wf_123', 'job_456');\n * console.log('Job status:', job.status);\n * ```\n */\n get(workflowId: string, jobId: string): Promise<WorkflowJob>;\n\n /**\n * Get the status of all jobs in a workflow.\n *\n * Returns a summary of each job's status. The API does not store or return\n * the `key` a job was created with, so `key` is undefined; map keys to job\n * IDs from the `jobIds` array that `workflows.create()` returns.\n *\n * @param workflowId - The workflow ID\n * @example\n * ```typescript\n * const statuses = await client.workflows.jobs.getStatus('wf_123');\n * for (const s of statuses) {\n * console.log(`${s.jobId}: ${s.status}`);\n * }\n * ```\n */\n getStatus(workflowId: string): Promise<WorkflowJobStatus[]>;\n\n /**\n * Get job dependencies.\n *\n * @param jobId - The job ID\n * @example\n * ```typescript\n * const deps = await client.workflows.jobs.getDependencies('job_456');\n * console.log('Depends on:', deps.dependencies);\n * ```\n */\n getDependencies(jobId: string): Promise<JobWithDependencies>;\n\n /**\n * Add dependencies to a job.\n *\n * @param jobId - The job ID\n * @param params - Dependencies to add\n * @example\n * ```typescript\n * await client.workflows.jobs.addDependencies('job_456', {\n * dependsOnJobIds: ['job_123'],\n * });\n * ```\n */\n addDependencies(\n jobId: string,\n params: AddDependenciesParams,\n ): Promise<AddDependenciesResponse>;\n}\n\nexport class WorkflowsResource {\n /** Workflow job operations */\n readonly jobs: WorkflowJobOperations;\n\n constructor(private readonly http: HttpClient) {\n this.jobs = {\n list: this.listWorkflowJobs.bind(this),\n get: this.getWorkflowJob.bind(this),\n getStatus: this.getWorkflowJobsStatus.bind(this),\n getDependencies: this.getJobDependencies.bind(this),\n addDependencies: this.addJobDependencies.bind(this),\n };\n }\n\n /**\n * List all workflows\n */\n async list(params?: ListWorkflowsParams): Promise<WorkflowResponse[]> {\n return this.http.get<WorkflowResponse[]>(\"/workflows\", {\n params: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * Create a new workflow\n */\n async create(params: CreateWorkflowParams): Promise<CreateWorkflowResponse> {\n return this.http.post<CreateWorkflowResponse>(\"/workflows\", params);\n }\n\n /**\n * Get a workflow by ID\n */\n async get(id: string): Promise<WorkflowResponse> {\n const raw = await this.http.get<WorkflowGetPayload>(`/workflows/${id}`);\n return mapWorkflowGetResponse(raw);\n }\n\n /**\n * Cancel a workflow\n */\n async cancel(id: string): Promise<WorkflowResponse> {\n return this.http.post<WorkflowResponse>(`/workflows/${id}/cancel`);\n }\n\n /**\n * Retry a failed workflow\n *\n * Resets all failed/deadletter jobs back to pending and resumes the workflow.\n * Only workflows with status 'failed' can be retried.\n */\n async retry(id: string): Promise<WorkflowResponse> {\n return this.http.post<WorkflowResponse>(`/workflows/${id}/retry`);\n }\n\n // Workflow job operations (private implementations)\n //\n // The backend has no /workflows/{id}/jobs routes. Job rows and dependency\n // edges are on GET /workflows/{id} (WorkflowDetailResponse).\n\n private async listWorkflowJobs(workflowId: string): Promise<WorkflowJob[]> {\n const detail = await this.http.get<WorkflowDetailPayload>(\n `/workflows/${workflowId}`,\n );\n return mapWorkflowDetailJobs(detail);\n }\n\n private async getWorkflowJob(\n workflowId: string,\n jobId: string,\n ): Promise<WorkflowJob> {\n const jobs = await this.listWorkflowJobs(workflowId);\n const job = jobs.find((item) => item.id === jobId);\n if (!job) {\n throw new NotFoundError(\n `Job ${jobId} not found in workflow ${workflowId}`,\n );\n }\n return job;\n }\n\n private async getWorkflowJobsStatus(\n workflowId: string,\n ): Promise<WorkflowJobStatus[]> {\n const jobs = await this.listWorkflowJobs(workflowId);\n return jobs.map((job) => ({\n jobId: job.id,\n ...(job.key !== undefined && { key: job.key }),\n status: job.status,\n }));\n }\n\n private async getJobDependencies(\n jobId: string,\n ): Promise<JobWithDependencies> {\n return this.http.get<JobWithDependencies>(`/jobs/${jobId}/dependencies`);\n }\n\n private async addJobDependencies(\n jobId: string,\n params: AddDependenciesParams,\n ): Promise<AddDependenciesResponse> {\n const dependsOn = params.dependsOn ?? params.dependsOnJobIds ?? [];\n const mode =\n params.dependencyMode ??\n (params.dependencyType === \"any\" || params.dependencyType === \"all\"\n ? params.dependencyType\n : undefined);\n const raw = await this.http.post<{\n dependenciesAdded?: number;\n dependenciesMet?: boolean;\n }>(\n `/jobs/${jobId}/dependencies`,\n {\n depends_on: dependsOn,\n ...(mode ? { dependency_mode: mode } : {}),\n },\n { skipRequestConversion: true },\n );\n return {\n added: raw.dependenciesAdded ?? 0,\n dependenciesMet: raw.dependenciesMet ?? false,\n dependencies: [],\n };\n }\n}\n\ninterface WorkflowDetailPayload {\n id?: string;\n jobs?: Array<Record<string, unknown>>;\n dependencies?: Array<{\n parentJobId?: string;\n childJobId?: string;\n }>;\n}\n\n/** GET /workflows/{id} after camelCase conversion. */\nexport interface WorkflowGetPayload {\n id?: string;\n name?: string;\n status?: WorkflowResponse[\"status\"];\n createdAt?: string;\n completedAt?: string;\n totalJobs?: number;\n completedJobs?: number;\n failedJobs?: number;\n progressPercent?: number;\n progress?: {\n total?: number;\n completed?: number;\n failed?: number;\n };\n}\n\n/**\n * GET /workflows/{id} is WorkflowDetailResponse: counts live under\n * `progress`, not top-level total_jobs like list/cancel/retry.\n */\nexport function mapWorkflowGetResponse(\n raw: WorkflowGetPayload,\n): WorkflowResponse {\n const totalJobs = raw.totalJobs ?? raw.progress?.total ?? 0;\n const completedJobs = raw.completedJobs ?? raw.progress?.completed ?? 0;\n const failedJobs = raw.failedJobs ?? raw.progress?.failed ?? 0;\n const progressPercent =\n raw.progressPercent ??\n (totalJobs > 0 ? (completedJobs / totalJobs) * 100 : 0);\n return {\n id: String(raw.id ?? \"\"),\n name: String(raw.name ?? \"\"),\n status: raw.status ?? \"pending\",\n totalJobs,\n completedJobs,\n failedJobs,\n progressPercent,\n createdAt: String(raw.createdAt ?? \"\"),\n completedAt: raw.completedAt,\n };\n}\n\nfunction mapWorkflowDetailJobs(detail: WorkflowDetailPayload): WorkflowJob[] {\n const workflowId = String(detail.id ?? \"\");\n const deps = detail.dependencies ?? [];\n return (detail.jobs ?? []).map((job) => {\n const id = String(job.id ?? \"\");\n const timeoutMs =\n typeof job.timeoutMs === \"number\" ? job.timeoutMs : undefined;\n const errorObj = job.error;\n let error: string | undefined;\n if (typeof errorObj === \"string\") {\n error = errorObj;\n } else if (\n errorObj &&\n typeof errorObj === \"object\" &&\n \"message\" in errorObj\n ) {\n error = String((errorObj as { message: unknown }).message);\n }\n return {\n id,\n workflowId: String(job.workflowId ?? workflowId),\n // The API does not return the creation-time key (jobs store only a\n // workflow step), so there is nothing to put here unless a future\n // version sends one. Never fabricate \"\".\n ...(typeof job.key === \"string\" && job.key !== \"\" && { key: job.key }),\n queueName: String(job.queueName ?? job.queue ?? \"\"),\n status: job.status as WorkflowJob[\"status\"],\n payload: (job.payload as JsonObject) ?? {},\n result: (job.result as JsonObject | undefined) ?? undefined,\n error,\n dependsOn: deps\n .filter((dep) => dep.childJobId === id)\n .map((dep) => String(dep.parentJobId ?? \"\")),\n priority: Number(job.priority ?? 0),\n maxRetries: Number(job.maxRetries ?? 0),\n attempt: Number(job.attempt ?? 0),\n timeoutSeconds:\n timeoutMs != null\n ? Math.max(1, Math.floor(timeoutMs / 1000))\n : undefined,\n createdAt: String(job.createdAt ?? \"\"),\n startedAt: (job.startedAt as string | undefined) ?? undefined,\n completedAt: (job.completedAt as string | undefined) ?? undefined,\n };\n });\n}\n","/**\n * Webhooks Resource\n *\n * Handles outgoing webhook operations.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type {\n OutgoingWebhook,\n CreateOutgoingWebhookParams,\n UpdateOutgoingWebhookParams,\n TestWebhookResponse,\n OutgoingWebhookDelivery,\n} from \"../types/webhooks.js\";\n\nexport class WebhooksResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all outgoing webhooks\n */\n async list(): Promise<OutgoingWebhook[]> {\n return this.http.get<OutgoingWebhook[]>(\"/outgoing-webhooks\");\n }\n\n /**\n * Create a new outgoing webhook\n */\n async create(params: CreateOutgoingWebhookParams): Promise<OutgoingWebhook> {\n return this.http.post<OutgoingWebhook>(\"/outgoing-webhooks\", params);\n }\n\n /**\n * Get an outgoing webhook by ID\n */\n async get(id: string): Promise<OutgoingWebhook> {\n return this.http.get<OutgoingWebhook>(`/outgoing-webhooks/${id}`);\n }\n\n /**\n * Update an outgoing webhook\n */\n async update(\n id: string,\n params: UpdateOutgoingWebhookParams,\n ): Promise<OutgoingWebhook> {\n return this.http.put<OutgoingWebhook>(`/outgoing-webhooks/${id}`, params);\n }\n\n /**\n * Delete an outgoing webhook\n */\n async delete(id: string): Promise<void> {\n await this.http.delete(`/outgoing-webhooks/${id}`);\n }\n\n /**\n * Test an outgoing webhook\n */\n async test(id: string): Promise<TestWebhookResponse> {\n return this.http.post<TestWebhookResponse>(`/outgoing-webhooks/${id}/test`);\n }\n\n /**\n * Get webhook delivery history\n */\n async getDeliveries(id: string): Promise<OutgoingWebhookDelivery[]> {\n return this.http.get<OutgoingWebhookDelivery[]>(\n `/outgoing-webhooks/${id}/deliveries`,\n );\n }\n\n /**\n * Retry a specific webhook delivery\n */\n async retryDelivery(\n webhookId: string,\n deliveryId: string,\n ): Promise<{ success: boolean; message: string }> {\n return this.http.post<{ success: boolean; message: string }>(\n `/outgoing-webhooks/${webhookId}/retry/${deliveryId}`,\n );\n }\n}\n","/**\n * API Keys Resource\n *\n * Handles API key operations.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type {\n ApiKeySummary,\n CreateApiKeyParams,\n CreateApiKeyResponse,\n UpdateApiKeyParams,\n} from \"../types/api-keys.js\";\n\nexport class ApiKeysResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all API keys (without sensitive data)\n */\n async list(): Promise<ApiKeySummary[]> {\n return this.http.get<ApiKeySummary[]>(\"/api-keys\");\n }\n\n /**\n * Create a new API key\n */\n async create(params: CreateApiKeyParams): Promise<CreateApiKeyResponse> {\n return this.http.post<CreateApiKeyResponse>(\"/api-keys\", params);\n }\n\n /**\n * Get an API key by ID (without sensitive data)\n */\n async get(id: string): Promise<ApiKeySummary> {\n return this.http.get<ApiKeySummary>(`/api-keys/${id}`);\n }\n\n /**\n * Update an API key\n */\n async update(id: string, params: UpdateApiKeyParams): Promise<ApiKeySummary> {\n return this.http.put<ApiKeySummary>(`/api-keys/${id}`, params);\n }\n\n /**\n * Revoke an API key\n */\n async revoke(id: string): Promise<void> {\n await this.http.delete(`/api-keys/${id}`);\n }\n}\n","/**\n * Organizations Resource\n *\n * Handles organization operations including webhook token management.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport { UnsupportedOperationError } from \"../errors.js\";\nimport type {\n Organization,\n OrganizationSummary,\n CreateOrganizationParams,\n CreateOrganizationResponse,\n UpdateOrganizationParams,\n OrganizationUsage,\n OrganizationMember,\n CheckSlugResponse,\n WebhookTokenResponse,\n} from \"../types/organizations.js\";\n\nexport class OrganizationsResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Create a new organization (public endpoint, no auth required)\n */\n async create(\n params: CreateOrganizationParams,\n ): Promise<CreateOrganizationResponse> {\n return this.http.post<CreateOrganizationResponse>(\"/organizations\", params);\n }\n\n /**\n * List organizations\n */\n async list(): Promise<OrganizationSummary[]> {\n return this.http.get<OrganizationSummary[]>(\"/organizations\");\n }\n\n /**\n * Get an organization by ID\n */\n async get(id: string): Promise<Organization> {\n return this.http.get<Organization>(`/organizations/${id}`);\n }\n\n /**\n * Update an organization\n */\n async update(\n id: string,\n params: UpdateOrganizationParams,\n ): Promise<Organization> {\n return this.http.put<Organization>(`/organizations/${id}`, params);\n }\n\n /**\n * Delete an organization\n */\n async delete(id: string): Promise<void> {\n await this.http.delete(`/organizations/${id}`);\n }\n\n /**\n * Get organization usage and limits\n */\n async getUsage(): Promise<OrganizationUsage> {\n return this.http.get<OrganizationUsage>(\"/organizations/usage\");\n }\n\n /**\n * Get organization members\n */\n async getMembers(id: string): Promise<OrganizationMember[]> {\n return this.http.get<OrganizationMember[]>(`/organizations/${id}/members`);\n }\n\n /**\n * Check slug availability\n */\n async checkSlug(slug: string): Promise<CheckSlugResponse> {\n return this.http.get<CheckSlugResponse>(\"/organizations/check-slug\", {\n params: { slug },\n });\n }\n\n /**\n * Generate a unique slug from an organization name\n */\n async generateSlug(name: string): Promise<{ slug: string }> {\n return this.http.post<{ slug: string }>(\"/organizations/generate-slug\", {\n name,\n });\n }\n\n /**\n * Get the webhook token for the current organization.\n *\n * This token is used to verify incoming webhook payloads from Spooled.\n * Use this token to validate webhook signatures.\n *\n * @example\n * ```typescript\n * const { webhookToken, webhookUrl } = await client.organizations.getWebhookToken();\n * console.log('Webhook token:', webhookToken);\n * ```\n */\n async getWebhookToken(): Promise<WebhookTokenResponse> {\n return this.http.get<WebhookTokenResponse>(\"/organizations/webhook-token\");\n }\n\n /**\n * Regenerate the webhook token for the current organization.\n *\n * This invalidates the old token immediately. All webhook signature\n * verification using the old token will fail after regeneration.\n *\n * @example\n * ```typescript\n * const { webhookToken: newToken } = await client.organizations.regenerateWebhookToken();\n * console.log('New webhook token:', newToken);\n * ```\n */\n async regenerateWebhookToken(): Promise<WebhookTokenResponse> {\n return this.http.post<WebhookTokenResponse>(\n \"/organizations/webhook-token/regenerate\",\n );\n }\n\n /**\n * Clear/delete the webhook token for the current organization.\n *\n * @deprecated The API refuses this operation on purpose (an org without a\n * webhook token would have an open public ingestion endpoint) and always\n * answers with an error. This method now throws\n * {@link UnsupportedOperationError} without a network call; rotate the token\n * with {@link OrganizationsResource.regenerateWebhookToken} instead. It will\n * be removed in the next major release.\n */\n async clearWebhookToken(): Promise<void> {\n throw new UnsupportedOperationError(\n \"organizations.clearWebhookToken\",\n \"clearing the webhook token is not allowed; use organizations.regenerateWebhookToken() to rotate it\",\n );\n }\n}\n","/**\n * Billing Resource\n *\n * Stripe billing integration endpoints.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type {\n BillingStatus,\n CreateBillingPortalParams,\n CreateBillingPortalResponse,\n} from \"../types/billing.js\";\n\nexport class BillingResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Get billing status for the authenticated organization.\n *\n * GET /api/v1/billing/status\n */\n async getStatus(): Promise<BillingStatus> {\n return this.http.get<BillingStatus>(\"/billing/status\");\n }\n\n /**\n * Create a Stripe billing portal session.\n *\n * POST /api/v1/billing/portal\n */\n async createPortal(\n params: CreateBillingPortalParams,\n ): Promise<CreateBillingPortalResponse> {\n return this.http.post<CreateBillingPortalResponse>(\n \"/billing/portal\",\n params,\n );\n }\n}\n","/**\n * Dashboard Resource\n *\n * Provides aggregated dashboard data (used by the Spooled dashboard UI).\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type { DashboardData } from \"../types/dashboard.js\";\n\nexport class DashboardResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Get dashboard data for the current organization.\n *\n * GET /api/v1/dashboard\n */\n async get(): Promise<DashboardData> {\n return this.http.get<DashboardData>(\"/dashboard\");\n }\n}\n","/**\n * Health Resource\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type { HealthResponse } from \"../types/health.js\";\n\nexport class HealthResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Basic health check (public).\n *\n * GET /health\n */\n async get(): Promise<HealthResponse> {\n return this.http.get<HealthResponse>(\"/health\", { skipApiPrefix: true });\n }\n\n /**\n * Kubernetes liveness probe (public).\n *\n * GET /health/live\n */\n async liveness(): Promise<boolean> {\n try {\n await this.http.request<string>(\"/health/live\", {\n method: \"GET\",\n skipApiPrefix: true,\n skipRetry: true,\n });\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Kubernetes readiness probe (public).\n *\n * GET /health/ready\n */\n async readiness(): Promise<boolean> {\n try {\n await this.http.request<string>(\"/health/ready\", {\n method: \"GET\",\n skipApiPrefix: true,\n skipRetry: true,\n });\n return true;\n } catch {\n return false;\n }\n }\n}\n","/**\n * Metrics Resource\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\n\nexport class MetricsResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Prometheus metrics (public; may be protected by METRICS_TOKEN on the server).\n *\n * GET /metrics\n */\n async get(): Promise<string> {\n return this.http.get<string>(\"/metrics\", {\n skipApiPrefix: true,\n // Ensure we get the raw text response.\n headers: { Accept: \"text/plain\" },\n });\n }\n}\n","/**\n * Admin Resource\n *\n * Platform administration endpoints.\n * All endpoints require `X-Admin-Key` header.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type {\n AdminListOrganizationsParams,\n AdminOrganizationList,\n AdminOrganizationDetail,\n AdminUpdateOrganizationParams,\n AdminCreateOrganizationParams,\n AdminCreateOrganizationResponse,\n AdminCreateApiKeyParams,\n AdminApiKeyResponse,\n AdminDeleteOrganizationParams,\n AdminPlatformStats,\n AdminPlanLimits,\n} from \"../types/admin.js\";\nimport type { Organization } from \"../types/organizations.js\";\nimport { AuthenticationError } from \"../errors.js\";\n\nexport class AdminResource {\n constructor(\n private readonly http: HttpClient,\n private readonly adminKey: string | undefined,\n ) {}\n\n private headers(): Record<string, string> {\n if (!this.adminKey) {\n throw new AuthenticationError(\n \"Admin key is required for admin endpoints. Provide `adminKey` in SpooledClient config.\",\n );\n }\n return { \"X-Admin-Key\": this.adminKey };\n }\n\n /** GET /api/v1/admin/organizations */\n async listOrganizations(\n params?: AdminListOrganizationsParams,\n ): Promise<AdminOrganizationList> {\n const qp:\n | Record<string, string | number | boolean | undefined>\n | undefined = params\n ? {\n planTier: params.planTier,\n search: params.search,\n limit: params.limit,\n offset: params.offset,\n sortBy: params.sortBy,\n sortOrder: params.sortOrder,\n }\n : undefined;\n return this.http.get<AdminOrganizationList>(\"/admin/organizations\", {\n params: qp,\n headers: this.headers(),\n });\n }\n\n /** POST /api/v1/admin/organizations */\n async createOrganization(\n params: AdminCreateOrganizationParams,\n ): Promise<AdminCreateOrganizationResponse> {\n return this.http.post<AdminCreateOrganizationResponse>(\n \"/admin/organizations\",\n params,\n {\n headers: this.headers(),\n },\n );\n }\n\n /** GET /api/v1/admin/organizations/{id} */\n async getOrganization(id: string): Promise<AdminOrganizationDetail> {\n return this.http.get<AdminOrganizationDetail>(\n `/admin/organizations/${id}`,\n {\n headers: this.headers(),\n },\n );\n }\n\n /** PATCH /api/v1/admin/organizations/{id} */\n async updateOrganization(\n id: string,\n params: AdminUpdateOrganizationParams,\n ): Promise<Organization> {\n return this.http.patch<Organization>(`/admin/organizations/${id}`, params, {\n headers: this.headers(),\n });\n }\n\n /** DELETE /api/v1/admin/organizations/{id}?hard_delete=true */\n async deleteOrganization(\n id: string,\n params?: AdminDeleteOrganizationParams,\n ): Promise<void> {\n const qp:\n | Record<string, string | number | boolean | undefined>\n | undefined = params ? { hardDelete: params.hardDelete } : undefined;\n await this.http.delete(`/admin/organizations/${id}`, {\n headers: this.headers(),\n params: qp,\n });\n }\n\n /** POST /api/v1/admin/organizations/{id}/api-keys */\n async createApiKey(\n orgId: string,\n params: AdminCreateApiKeyParams,\n ): Promise<AdminApiKeyResponse> {\n return this.http.post<AdminApiKeyResponse>(\n `/admin/organizations/${orgId}/api-keys`,\n params,\n {\n headers: this.headers(),\n },\n );\n }\n\n /** POST /api/v1/admin/organizations/{id}/reset-usage */\n async resetUsage(orgId: string): Promise<void> {\n await this.http.post<void>(\n `/admin/organizations/${orgId}/reset-usage`,\n undefined,\n {\n headers: this.headers(),\n },\n );\n }\n\n /** GET /api/v1/admin/stats */\n async getStats(): Promise<AdminPlatformStats> {\n return this.http.get<AdminPlatformStats>(\"/admin/stats\", {\n headers: this.headers(),\n });\n }\n\n /** GET /api/v1/admin/plans */\n async listPlans(): Promise<AdminPlanLimits[]> {\n return this.http.get<AdminPlanLimits[]>(\"/admin/plans\", {\n headers: this.headers(),\n });\n }\n}\n","/**\n * Webhook Ingestion Resource\n *\n * The Spooled API ingests webhooks on one route:\n * `POST /api/v1/webhooks/{org_id}/custom`, authenticated by the org's webhook\n * token. The GitHub and Stripe routes were removed from the API.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type {\n InboundWebhookDelivery,\n IngestCustomWebhookParams,\n IngestCustomWebhookResponse,\n IngestGitHubWebhookOptions,\n IngestStripeWebhookOptions,\n ListInboundDeliveriesParams,\n} from \"../types/webhook-ingestion.js\";\nimport { UnsupportedOperationError } from \"../errors.js\";\nimport { toQueryTimestamp } from \"../utils/paging.js\";\n\nexport class WebhookIngestionResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Ingest a GitHub webhook.\n *\n * @deprecated The API has no `/webhooks/{org_id}/github` route (it always\n * answered 404). This method now throws {@link UnsupportedOperationError}\n * without a network call; point the GitHub webhook at `ingest.custom` /\n * `POST /api/v1/webhooks/{org_id}/custom` instead. It will be removed in the\n * next major release.\n */\n async github(\n _orgId: string,\n _body: string | Uint8Array | ArrayBuffer,\n _options: IngestGitHubWebhookOptions,\n ): Promise<void> {\n throw new UnsupportedOperationError(\n \"ingest.github\",\n \"the API has no GitHub webhook route; use ingest.custom (POST /webhooks/{org_id}/custom)\",\n );\n }\n\n /**\n * Ingest a Stripe webhook.\n *\n * @deprecated The API has no `/webhooks/{org_id}/stripe` route (it always\n * answered 404). This method now throws {@link UnsupportedOperationError}\n * without a network call; point the Stripe webhook at `ingest.custom` /\n * `POST /api/v1/webhooks/{org_id}/custom` instead. It will be removed in the\n * next major release.\n */\n async stripe(\n _orgId: string,\n _body: string | Uint8Array | ArrayBuffer,\n _options: IngestStripeWebhookOptions = {},\n ): Promise<void> {\n throw new UnsupportedOperationError(\n \"ingest.stripe\",\n \"the API has no Stripe webhook route; use ingest.custom (POST /webhooks/{org_id}/custom)\",\n );\n }\n\n /**\n * Ingest a custom webhook.\n *\n * POST /api/v1/webhooks/{org_id}/custom returns `{ jobId, queueName, status }`.\n * An older empty 200 maps to an empty object rather than throwing.\n */\n async custom(\n orgId: string,\n params: IngestCustomWebhookParams,\n opts?: { webhookToken?: string; forwardedProto?: string },\n ): Promise<IngestCustomWebhookResponse> {\n const headers: Record<string, string> = {\n ...(opts?.webhookToken ? { \"X-Webhook-Token\": opts.webhookToken } : {}),\n ...(opts?.forwardedProto\n ? { \"X-Forwarded-Proto\": opts.forwardedProto }\n : {}),\n };\n\n const raw = await this.http.post<IngestCustomWebhookResponse | string>(\n `/webhooks/${orgId}/custom`,\n params,\n { headers },\n );\n if (!raw || typeof raw === \"string\") {\n return {};\n }\n return {\n jobId: raw.jobId,\n queueName: raw.queueName,\n status: raw.status,\n };\n }\n\n /**\n * The inbound webhook log: accepted requests to\n * `POST /webhooks/{org_id}/custom`, newest first\n * (`GET /webhooks/deliveries`, API 0.1.122+).\n *\n * Needs an API key without a queue restriction (a queue-scoped key gets a\n * 403 `AuthorizationError`). Entries carry no payload and no signature;\n * requests that were rejected are not logged. `limit` defaults to 50 (at\n * most 100); an invalid filter is a 400 `ValidationError`.\n */\n async listDeliveries(\n params?: ListInboundDeliveriesParams,\n ): Promise<InboundWebhookDelivery[]> {\n const rows = await this.http.get<InboundWebhookDelivery[]>(\n \"/webhooks/deliveries\",\n {\n params: {\n status: params?.status,\n since: toQueryTimestamp(params?.since),\n queueName: params?.queueName,\n limit: params?.limit,\n offset: params?.offset,\n },\n },\n );\n return rows ?? [];\n }\n}\n","/**\n * Backend → SDK realtime event-name mapping.\n *\n * The backend's `RealtimeEvent` enum is serialized with\n * `#[serde(tag = \"type\", content = \"data\")]`, so events arrive on the wire as\n * `{ \"type\": \"<PascalCaseVariant>\", \"data\": { ...snake_case fields } }`, e.g.\n * `{ \"type\": \"JobCompleted\", \"data\": { \"job_id\": \"…\", \"duration_ms\": 12 } }`.\n *\n * The SDK's public event API, however, uses dotted names (`job.completed`,\n * `queue.stats`, …). Without translation, `rt.on('job.completed', …)` never\n * fires because the transport dispatches under the raw wire name\n * (`JobCompleted`). This map bridges the two: every variant of the backend enum\n * maps to its dotted SDK name.\n */\nexport const BACKEND_EVENT_TYPE_MAP: Record<string, string> = {\n JobStatusChange: \"job.status_changed\",\n JobCreated: \"job.created\",\n JobCompleted: \"job.completed\",\n JobFailed: \"job.failed\",\n QueueStats: \"queue.stats\",\n WorkerHeartbeat: \"worker.heartbeat\",\n WorkerRegistered: \"worker.registered\",\n WorkerDeregistered: \"worker.deregistered\",\n SystemHealth: \"system.health\",\n Ping: \"ping\",\n Error: \"error\",\n};\n\n/**\n * Translate a wire event `type` to the SDK's dotted event name.\n *\n * Names that are already dotted (or otherwise unknown) pass through unchanged,\n * so this is safe to call on every inbound message and keeps working if the\n * backend ever starts sending pre-dotted names.\n */\nexport function mapEventType(type: string): string {\n return BACKEND_EVENT_TYPE_MAP[type] ?? type;\n}\n","/**\n * WebSocket Realtime Client\n *\n * Provides real-time event streaming over WebSocket.\n */\n\nimport type {\n RealtimeConnectionOptions,\n RealtimeEvent,\n RealtimeEventType,\n SubscriptionFilter,\n ConnectionState,\n WebSocketCommand,\n} from \"./types.js\";\nimport { convertResponse } from \"../utils/casing.js\";\nimport { mapEventType } from \"./event-map.js\";\n\n/** Event handler type - simplified for internal use */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EventHandler = (data: any) => void;\n\n/** Generic event handler */\ntype GenericEventHandler = (event: RealtimeEvent) => void;\n\n/**\n * WebSocket Realtime Client\n *\n * Connects to the Spooled API WebSocket endpoint and emits typed events.\n */\nexport class WebSocketRealtimeClient {\n private readonly options: Required<RealtimeConnectionOptions>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private ws: any = null;\n private state: ConnectionState = \"disconnected\";\n private reconnectAttempts = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n /**\n * Set when the server rejected our token on the upgrade (e.g. HTTP 401/403).\n * The next (re)connect uses it to force the token provider to mint a fresh\n * JWT instead of replaying the rejected one (which would loop forever).\n */\n private authFailure = false;\n private subscriptions: Map<string, SubscriptionFilter> = new Map();\n\n // Event handlers\n private eventHandlers: Map<RealtimeEventType, Set<EventHandler>> = new Map();\n private allEventsHandlers: Set<GenericEventHandler> = new Set();\n private stateChangeHandlers: Set<(state: ConnectionState) => void> =\n new Set();\n\n constructor(options: RealtimeConnectionOptions) {\n // All defaults are applied AFTER the spread. SpooledRealtime forwards each of\n // these options as possibly-`undefined`, and a pre-spread default is clobbered\n // by an explicit `undefined` — e.g. autoReconnect would resolve to undefined\n // (falsy), silently disabling reconnect despite the documented default `true`,\n // and debug would become undefined and throw when connect() calls it.\n this.options = {\n ...options,\n autoReconnect: options.autoReconnect ?? true,\n maxReconnectAttempts: options.maxReconnectAttempts ?? 10,\n reconnectDelay: options.reconnectDelay ?? 1000,\n maxReconnectDelay: options.maxReconnectDelay ?? 30000,\n // Always resolve to a provider so reconnects can mint a fresh JWT.\n // Falls back to the static token when no provider is supplied.\n tokenProvider: options.tokenProvider ?? (async () => options.token),\n debug: options.debug ?? (() => {}),\n };\n }\n\n /**\n * Get current connection state\n */\n getState(): ConnectionState {\n return this.state;\n }\n\n /**\n * Get WebSocket implementation (browser native or Node.js ws package)\n */\n private async getWebSocketImpl(): Promise<typeof WebSocket> {\n if (typeof WebSocket !== \"undefined\") {\n return WebSocket;\n }\n // Node.js environment - use ws package with dynamic import for ESM compatibility\n const wsModule = await import(\"ws\");\n return wsModule.default as unknown as typeof WebSocket;\n }\n\n /**\n * Connect to the WebSocket server\n */\n async connect(): Promise<void> {\n if (this.state === \"connected\" || this.state === \"connecting\") {\n return;\n }\n\n this.setState(\"connecting\");\n\n // Build WebSocket URL with a freshly-minted token\n let wsUrl: string;\n try {\n wsUrl = await this.buildWsUrl();\n } catch (error) {\n this.setState(\"disconnected\");\n throw new Error(`Failed to acquire realtime token: ${error}`);\n }\n // Redact the token query param so JWTs never land in logs.\n this.options.debug(`Connecting to ${redactToken(wsUrl)}`);\n\n // Get WebSocket implementation (async for ESM compatibility in Node.js)\n let WebSocketImpl: typeof WebSocket;\n try {\n WebSocketImpl = await this.getWebSocketImpl();\n } catch (error) {\n this.setState(\"disconnected\");\n throw new Error(`Failed to load WebSocket implementation: ${error}`);\n }\n\n return new Promise((resolve, reject) => {\n try {\n this.ws = new WebSocketImpl(wsUrl);\n\n this.ws.onopen = () => {\n this.options.debug(\"WebSocket connected\");\n this.setState(\"connected\");\n this.reconnectAttempts = 0;\n this.resubscribeAll();\n resolve();\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.ws.onmessage = (event: any) => {\n this.handleMessage(\n typeof event.data === \"string\" ? event.data : String(event.data),\n );\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.ws.onclose = (event: any) => {\n this.options.debug(`WebSocket closed: ${event.code} ${event.reason}`);\n const wasConnecting = this.state === \"connecting\";\n this.handleDisconnect();\n if (wasConnecting) {\n reject(\n new Error(\n `WebSocket connection failed: ${event.reason || \"Unknown error\"}`,\n ),\n );\n }\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.ws.onerror = (event: any) => {\n this.options.debug(\"WebSocket error\", event);\n // The Node `ws` package surfaces a rejected upgrade here as an error\n // whose message is e.g. \"Unexpected server response: 401\". Flag it so\n // the next reconnect forces a fresh token rather than replaying the\n // rejected one. (Browsers don't expose the status; expiry-based\n // refresh still covers the common case there.)\n if (isAuthFailureEvent(event)) {\n this.authFailure = true;\n }\n };\n } catch (error) {\n this.setState(\"disconnected\");\n reject(error);\n }\n });\n }\n\n /**\n * Disconnect from the WebSocket server\n */\n disconnect(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n if (this.ws) {\n this.ws.onclose = null; // Prevent reconnect\n this.ws.close(1000, \"Client disconnect\");\n this.ws = null;\n }\n\n this.setState(\"disconnected\");\n this.subscriptions.clear();\n }\n\n /**\n * Subscribe to events matching a filter.\n *\n * The server applies filtering itself and sends no acknowledgement, so this\n * resolves as soon as the command has been written to the socket. The filter\n * is tracked locally so it is replayed automatically on reconnect.\n */\n async subscribe(filter: SubscriptionFilter): Promise<void> {\n const filterId = this.filterToId(filter);\n\n if (this.subscriptions.has(filterId)) {\n return; // Already subscribed\n }\n\n this.subscriptions.set(filterId, filter);\n\n if (this.state === \"connected\") {\n this.sendCommand(\"Subscribe\", filter);\n }\n }\n\n /**\n * Unsubscribe from events matching a filter.\n *\n * Fire-and-forget, like {@link subscribe} — the server sends no ack.\n */\n async unsubscribe(filter: SubscriptionFilter): Promise<void> {\n const filterId = this.filterToId(filter);\n\n if (!this.subscriptions.has(filterId)) {\n return; // Not subscribed\n }\n\n this.subscriptions.delete(filterId);\n\n if (this.state === \"connected\") {\n this.sendCommand(\"Unsubscribe\", filter);\n }\n }\n\n /**\n * Add an event listener for a specific event type\n */\n on<T extends RealtimeEventType>(type: T, handler: EventHandler): () => void {\n if (!this.eventHandlers.has(type)) {\n this.eventHandlers.set(type, new Set());\n }\n this.eventHandlers.get(type)!.add(handler);\n\n // Return unsubscribe function\n return () => this.off(type, handler);\n }\n\n /**\n * Remove an event listener\n */\n off<T extends RealtimeEventType>(type: T, handler: EventHandler): void {\n const handlers = this.eventHandlers.get(type);\n if (handlers) {\n handlers.delete(handler);\n }\n }\n\n /**\n * Add a listener for all events\n */\n onEvent(handler: GenericEventHandler): () => void {\n this.allEventsHandlers.add(handler);\n return () => this.allEventsHandlers.delete(handler);\n }\n\n /**\n * Add a listener for state changes\n */\n onStateChange(handler: (state: ConnectionState) => void): () => void {\n this.stateChangeHandlers.add(handler);\n return () => this.stateChangeHandlers.delete(handler);\n }\n\n // Private methods\n\n private async buildWsUrl(): Promise<string> {\n // wsUrl should already be ws:// or wss://\n const wsBase = this.options.wsUrl;\n // Reuse the provider's cached JWT unless the previous attempt was rejected\n // for auth (401/403 on the upgrade), in which case force a fresh token so a\n // stale/revoked one can't block recovery. Clear the flag either way.\n const forceRefresh = this.authFailure;\n this.authFailure = false;\n const token = await this.options.tokenProvider(forceRefresh);\n return `${wsBase}/api/v1/ws?token=${encodeURIComponent(token)}`;\n }\n\n private setState(state: ConnectionState): void {\n if (this.state !== state) {\n this.state = state;\n this.stateChangeHandlers.forEach((handler) => handler(state));\n }\n }\n\n private handleMessage(data: string): void {\n try {\n // Backend emits snake_case; convert to camelCase to match the typed\n // event shapes (jobId, queueName, durationMs, ...). User blobs like\n // `result`/`payload` are preserved via SKIP_CONVERSION_KEYS.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const message = convertResponse(JSON.parse(data)) as any;\n\n // The backend tags events with the PascalCase enum variant name\n // (`JobCompleted`, `QueueStats`, ...); the SDK's public API dispatches by\n // dotted name (`job.completed`, `queue.stats`). Translate before dispatch\n // so `on('job.completed', ...)` fires. Unknown/pre-dotted names pass\n // through unchanged.\n const eventType = mapEventType(String(message.type));\n message.type = eventType;\n const event = message as RealtimeEvent;\n this.options.debug(`Received event: ${eventType}`, event);\n\n // Emit to specific handlers\n const handlers = this.eventHandlers.get(eventType as RealtimeEventType);\n if (handlers) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const eventData = (event as any).data;\n handlers.forEach((handler) => {\n try {\n handler(eventData);\n } catch (error) {\n this.options.debug(\"Event handler error\", error);\n }\n });\n }\n\n // Emit to all-events handlers\n this.allEventsHandlers.forEach((handler) => {\n try {\n handler(event);\n } catch (error) {\n this.options.debug(\"Event handler error\", error);\n }\n });\n } catch (error) {\n this.options.debug(\"Failed to parse message\", { data, error });\n }\n }\n\n private handleDisconnect(): void {\n this.ws = null;\n\n if (\n this.options.autoReconnect &&\n this.reconnectAttempts < this.options.maxReconnectAttempts\n ) {\n this.scheduleReconnect();\n } else {\n this.setState(\"disconnected\");\n }\n }\n\n private scheduleReconnect(): void {\n this.setState(\"reconnecting\");\n this.reconnectAttempts++;\n\n const baseDelay = Math.min(\n this.options.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1),\n this.options.maxReconnectDelay,\n );\n // Add randomized jitter (up to +25%) to avoid a thundering-herd reconnect\n // storm when many clients drop at the same moment. Matches utils/retry.ts.\n const delay = Math.floor(baseDelay + Math.random() * baseDelay * 0.25);\n\n this.options.debug(\n `Scheduling reconnect attempt ${this.reconnectAttempts} in ${delay}ms`,\n );\n\n this.reconnectTimer = setTimeout(async () => {\n try {\n await this.connect();\n } catch (error) {\n this.options.debug(\"Reconnect failed\", error);\n if (\n this.options.autoReconnect &&\n this.reconnectAttempts < this.options.maxReconnectAttempts\n ) {\n this.scheduleReconnect();\n } else {\n this.setState(\"disconnected\");\n }\n }\n }, delay);\n }\n\n private resubscribeAll(): void {\n for (const filter of this.subscriptions.values()) {\n try {\n this.sendCommand(\"Subscribe\", filter);\n } catch (error) {\n this.options.debug(\"Failed to resubscribe\", { filter, error });\n }\n }\n }\n\n /**\n * Send a subscribe/unsubscribe command to the server.\n *\n * The backend `ClientCommand` shape is `{ cmd, queue, job_id }` and it sends\n * no acknowledgement, so this is fire-and-forget — it writes to the socket\n * and returns. The `SubscriptionFilter`'s `workerId`/`scheduleId` have no\n * server-side equivalent and are ignored.\n */\n private sendCommand(\n cmd: \"Subscribe\" | \"Unsubscribe\",\n filter: SubscriptionFilter,\n ): void {\n if (!this.ws || this.state !== \"connected\") {\n throw new Error(\"WebSocket not connected\");\n }\n\n const command: WebSocketCommand = {\n cmd,\n queue: filter.queueName,\n job_id: filter.jobId,\n };\n this.ws.send(JSON.stringify(command));\n }\n\n private filterToId(filter: SubscriptionFilter): string {\n return JSON.stringify(filter);\n }\n}\n\n/**\n * Redact sensitive auth query params (token/api_key) from a URL for logging.\n */\nexport function redactToken(url: string): string {\n return url.replace(/([?&](?:token|api_key)=)[^&]*/gi, \"$1***\");\n}\n\n/**\n * Detect whether a WebSocket error event represents an auth rejection on the\n * upgrade (HTTP 401/403). The Node `ws` package reports these as an error whose\n * message is like \"Unexpected server response: 401\"; different runtimes may put\n * the text on `message`, `error.message`, or `reason`.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isAuthFailureEvent(event: any): boolean {\n if (!event) {\n return false;\n }\n const status = event.status ?? event.statusCode ?? event.error?.status;\n if (status === 401 || status === 403) {\n return true;\n }\n const text = String(\n event.message ?? event.error?.message ?? event.reason ?? \"\",\n );\n return /\\b(401|403)\\b/.test(text);\n}\n","/**\n * SSE Realtime Client\n *\n * Provides real-time event streaming over Server-Sent Events.\n */\n\nimport type {\n RealtimeConnectionOptions,\n RealtimeEvent,\n RealtimeEventType,\n SubscriptionFilter,\n ConnectionState,\n} from \"./types.js\";\nimport { convertResponse } from \"../utils/casing.js\";\nimport { mapEventType } from \"./event-map.js\";\n\n/** Event handler type - simplified for internal use */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EventHandler = (data: any) => void;\n\n/** Generic event handler */\ntype GenericEventHandler = (event: RealtimeEvent) => void;\n\n/**\n * Every SSE `event:` name the API sends. The server always names its frames\n * (`event: job.completed`), and an EventSource delivers named frames only to\n * `addEventListener(name, ...)` — `onmessage` sees unnamed frames alone — so\n * without these listeners the client received nothing at all.\n */\nexport const SSE_EVENT_NAMES = [\n \"job.created\",\n \"job.status\",\n \"job.completed\",\n \"job.failed\",\n \"queue.stats\",\n \"worker.heartbeat\",\n \"worker.registered\",\n \"worker.deregistered\",\n \"system.health\",\n \"ping\",\n \"error\",\n] as const;\n\n/**\n * Job statuses after which the API closes a job stream\n * (`/events/jobs/{id}` ends once the job reaches one of these).\n */\nconst TERMINAL_JOB_STATUSES = new Set([\n \"completed\",\n \"failed\",\n \"deadletter\",\n \"cancelled\",\n]);\n\n/**\n * How long a connection must stay open before it counts as healthy and gives\n * the next reconnect a fresh attempt budget. A stream the server closes right\n * after opening is not healthy, however \"successfully\" it opened.\n */\nconst STABLE_CONNECTION_MS = 30_000;\n\n/**\n * SSE Realtime Client\n *\n * Connects to the Spooled API SSE endpoint and emits typed events.\n * SSE is unidirectional - subscriptions must be set at connection time.\n */\nexport class SseRealtimeClient {\n private readonly options: Required<RealtimeConnectionOptions>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private eventSource: any = null;\n private state: ConnectionState = \"disconnected\";\n private reconnectAttempts = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private filter: SubscriptionFilter | null = null;\n /** When the current connection opened (for the stable-connection check). */\n private connectedAt: number | null = null;\n /** The server finished this stream on purpose (terminal job); do not reconnect. */\n private streamEnded = false;\n /** The server rejected our token; mint a fresh one for the next connect. */\n private forceTokenRefresh = false;\n\n // Event handlers\n private eventHandlers: Map<RealtimeEventType, Set<EventHandler>> = new Map();\n private allEventsHandlers: Set<GenericEventHandler> = new Set();\n private stateChangeHandlers: Set<(state: ConnectionState) => void> =\n new Set();\n\n constructor(options: RealtimeConnectionOptions) {\n // Defaults applied AFTER the spread — a pre-spread default is clobbered by an\n // explicit `undefined` forwarded from SpooledRealtime (e.g. autoReconnect would\n // resolve to undefined/falsy, silently disabling reconnect despite the\n // documented default `true`).\n this.options = {\n ...options,\n autoReconnect: options.autoReconnect ?? true,\n maxReconnectAttempts: options.maxReconnectAttempts ?? 10,\n reconnectDelay: options.reconnectDelay ?? 1000,\n maxReconnectDelay: options.maxReconnectDelay ?? 30000,\n // Always resolve to a provider so reconnects can mint a fresh token.\n // Falls back to the static token when no provider is supplied.\n tokenProvider: options.tokenProvider ?? (async () => options.token),\n // Coalesce debug to a no-op AFTER the spread. A caller that omits debug\n // still passes `debug: undefined` explicitly (e.g. via SpooledRealtime),\n // and spreading that would overwrite a pre-spread default with undefined,\n // making connect() call `this.options.debug(...)` on undefined and throw\n // \"this.options.debug is not a function\". Guarding here keeps it callable\n // regardless of what the caller passes.\n debug: options.debug ?? (() => {}),\n };\n }\n\n /**\n * Get current connection state\n */\n getState(): ConnectionState {\n return this.state;\n }\n\n /**\n * Connect to the SSE server with a subscription filter\n */\n async connect(filter?: SubscriptionFilter): Promise<void> {\n if (this.state === \"connected\" || this.state === \"connecting\") {\n return;\n }\n\n this.filter = filter || null;\n this.streamEnded = false;\n\n this.setState(\"connecting\");\n\n const sseUrl = this.buildSseUrl(filter);\n this.options.debug(`Connecting to SSE: ${sseUrl}`);\n\n // Use eventsource package in Node.js, native EventSource in browser\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let EventSourceImpl: any;\n if (typeof EventSource !== \"undefined\") {\n EventSourceImpl = EventSource;\n } else {\n // Dynamic import for ESM compatibility\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod = (await import(\"eventsource\")) as any;\n EventSourceImpl = mod.default || mod.EventSource || mod;\n } catch {\n this.setState(\"disconnected\");\n throw new Error(\n \"eventsource package is required for SSE in Node.js. Install it with: npm install eventsource\",\n );\n }\n }\n\n // Ask the provider on every (re)connect so a stale token never blocks\n // recovery. It caches the JWT itself, so only force a new login after the\n // server actually rejected the token (a 401/403), not on every retry.\n let token: string;\n try {\n const force = this.forceTokenRefresh;\n this.forceTokenRefresh = false;\n token = await this.options.tokenProvider(force);\n } catch (error) {\n this.setState(\"disconnected\");\n throw new Error(`Failed to acquire realtime token: ${error}`);\n }\n\n return new Promise((resolve, reject) => {\n try {\n // Create EventSource with authorization header\n // Note: eventsource v4 changed API - headers are now passed via custom fetch\n this.eventSource = new EventSourceImpl(sseUrl, {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n fetch: (input: any, init: any) =>\n fetch(input, {\n ...init,\n headers: {\n ...init?.headers,\n Authorization: `Bearer ${token}`,\n },\n }),\n });\n\n this.eventSource.onopen = () => {\n this.options.debug(\"SSE connected\");\n this.setState(\"connected\");\n // The attempt counter is NOT reset here: an open that the server\n // closes at once (a finished job's stream) would otherwise refill the\n // budget on every cycle and reconnect forever. It resets once the\n // connection has proved stable (see handleDisconnect).\n this.connectedAt = Date.now();\n resolve();\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.eventSource.onmessage = (event: any) => {\n this.handleMessage(event.data);\n };\n for (const name of SSE_EVENT_NAMES) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.eventSource.addEventListener(name, (event: any) => {\n // \"error\" also fires for connection failures, which carry no data\n // and are handled by onerror below.\n if (typeof event?.data === \"string\") this.handleMessage(event.data);\n });\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.eventSource.onerror = (event: any) => {\n this.options.debug(\"SSE error\");\n\n // The `eventsource` package reports the HTTP status of a rejected\n // connection as `code`.\n if (event?.code === 401 || event?.code === 403) {\n this.forceTokenRefresh = true;\n }\n\n if (this.state === \"connecting\") {\n this.setState(\"disconnected\");\n // Close the abandoned EventSource so it doesn't keep auto-reconnecting\n // in the background after we reject the initial connect promise.\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n reject(new Error(\"SSE connection failed\"));\n return;\n }\n\n this.handleDisconnect();\n };\n } catch (error) {\n this.setState(\"disconnected\");\n reject(error);\n }\n });\n }\n\n /**\n * Disconnect from the SSE server\n */\n disconnect(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n\n this.setState(\"disconnected\");\n this.filter = null;\n this.connectedAt = null;\n this.streamEnded = false;\n }\n\n /**\n * Reconnect with a new filter (SSE requires reconnection to change subscriptions)\n */\n async reconnect(filter?: SubscriptionFilter): Promise<void> {\n this.disconnect();\n await this.connect(filter);\n }\n\n /**\n * Add an event listener for a specific event type\n */\n on<T extends RealtimeEventType>(type: T, handler: EventHandler): () => void {\n if (!this.eventHandlers.has(type)) {\n this.eventHandlers.set(type, new Set());\n }\n this.eventHandlers.get(type)!.add(handler);\n\n return () => this.off(type, handler);\n }\n\n /**\n * Remove an event listener\n */\n off<T extends RealtimeEventType>(type: T, handler: EventHandler): void {\n const handlers = this.eventHandlers.get(type);\n if (handlers) {\n handlers.delete(handler);\n }\n }\n\n /**\n * Add a listener for all events\n */\n onEvent(handler: GenericEventHandler): () => void {\n this.allEventsHandlers.add(handler);\n return () => this.allEventsHandlers.delete(handler);\n }\n\n /**\n * Add a listener for state changes\n */\n onStateChange(handler: (state: ConnectionState) => void): () => void {\n this.stateChangeHandlers.add(handler);\n return () => this.stateChangeHandlers.delete(handler);\n }\n\n // Private methods\n\n private buildSseUrl(filter?: SubscriptionFilter): string {\n // Backend SSE endpoints:\n // - GET /api/v1/events (every org event; ?queue= narrows it to one queue)\n // - GET /api/v1/events/jobs/{id} (single job status stream)\n // - GET /api/v1/events/queues/{name} (queue.stats counters only)\n //\n // A queue subscription uses /events?queue=: the per-queue route carries only\n // queue.stats, so `on('job.created')` after `subscribe({ queueName })` would\n // never fire there. Requires API 0.1.114+.\n if (filter?.jobId) {\n return `${this.options.baseUrl}/api/v1/events/jobs/${encodeURIComponent(filter.jobId)}`;\n }\n if (filter?.queueName) {\n return `${this.options.baseUrl}/api/v1/events?queue=${encodeURIComponent(filter.queueName)}`;\n }\n return `${this.options.baseUrl}/api/v1/events`;\n }\n\n private setState(state: ConnectionState): void {\n if (this.state !== state) {\n this.state = state;\n this.stateChangeHandlers.forEach((handler) => handler(state));\n }\n }\n\n private handleMessage(data: string): void {\n try {\n // Backend emits snake_case; convert to camelCase to match the typed\n // event shapes. User blobs (`result`/`payload`) are preserved via\n // SKIP_CONVERSION_KEYS.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const parsed = convertResponse(JSON.parse(data)) as any;\n // Translate the backend's PascalCase variant name (`JobCompleted`) to the\n // SDK's dotted event name (`job.completed`) before dispatch, matching the\n // WebSocket client. Unknown/pre-dotted names pass through unchanged.\n const eventType = mapEventType(String(parsed.type));\n parsed.type = eventType;\n const event = parsed as RealtimeEvent;\n this.options.debug(`Received SSE event: ${eventType}`, event);\n\n // A job stream ends once the job is terminal; remember it so the close\n // that follows is not treated as a dropped connection.\n if (this.filter?.jobId && isStreamEndingEvent(eventType, parsed.data)) {\n this.streamEnded = true;\n }\n\n // Emit to specific handlers\n const handlers = this.eventHandlers.get(eventType as RealtimeEventType);\n if (handlers) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const eventData = (event as any).data;\n handlers.forEach((handler) => {\n try {\n handler(eventData);\n } catch (error) {\n this.options.debug(\"Event handler error\", error);\n }\n });\n }\n\n // Emit to all-events handlers\n this.allEventsHandlers.forEach((handler) => {\n try {\n handler(event);\n } catch (error) {\n this.options.debug(\"Event handler error\", error);\n }\n });\n } catch (error) {\n this.options.debug(\"Failed to parse SSE message\", { data, error });\n }\n }\n\n private handleDisconnect(): void {\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n\n // The server ended this stream deliberately (a terminal job): reconnecting\n // would only replay the terminal event again and again.\n if (this.streamEnded) {\n this.connectedAt = null;\n this.setState(\"disconnected\");\n return;\n }\n\n // A connection that stayed up long enough was healthy (e.g. the server's\n // 30 minute cap closed it): give the reconnect a fresh budget. One that\n // closed right after opening keeps counting toward maxReconnectAttempts.\n if (\n this.connectedAt !== null &&\n Date.now() - this.connectedAt >= STABLE_CONNECTION_MS\n ) {\n this.reconnectAttempts = 0;\n }\n this.connectedAt = null;\n\n if (\n this.options.autoReconnect &&\n this.reconnectAttempts < this.options.maxReconnectAttempts\n ) {\n this.scheduleReconnect();\n } else {\n this.setState(\"disconnected\");\n }\n }\n\n private scheduleReconnect(): void {\n this.setState(\"reconnecting\");\n this.reconnectAttempts++;\n\n const baseDelay = Math.min(\n this.options.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1),\n this.options.maxReconnectDelay,\n );\n // Add randomized jitter (up to +25%) to avoid synchronized reconnect\n // storms across clients. Matches utils/retry.ts.\n const delay = Math.floor(baseDelay + Math.random() * baseDelay * 0.25);\n\n this.options.debug(\n `Scheduling SSE reconnect attempt ${this.reconnectAttempts} in ${delay}ms`,\n );\n\n this.reconnectTimer = setTimeout(async () => {\n try {\n await this.connect(this.filter || undefined);\n } catch (error) {\n this.options.debug(\"SSE reconnect failed\", error);\n if (\n this.options.autoReconnect &&\n this.reconnectAttempts < this.options.maxReconnectAttempts\n ) {\n this.scheduleReconnect();\n } else {\n this.setState(\"disconnected\");\n }\n }\n }, delay);\n }\n}\n\n/**\n * Whether an inbound event means the API is about to close this job stream:\n * the job reached a terminal status, or the server sent its own `error` (e.g.\n * \"Job not found\"), which it follows by closing the stream.\n */\nfunction isStreamEndingEvent(eventType: string, data: unknown): boolean {\n if (eventType === \"error\" || eventType === \"job.completed\") {\n return true;\n }\n const record = (data ?? {}) as { newStatus?: unknown; willRetry?: unknown };\n if (eventType === \"job.failed\") {\n return record.willRetry === false;\n }\n if (eventType === \"job.status_changed\" || eventType === \"job.status\") {\n return (\n typeof record.newStatus === \"string\" &&\n TERMINAL_JOB_STATUSES.has(record.newStatus)\n );\n }\n return false;\n}\n","/**\n * Realtime Module\n *\n * Provides WebSocket and SSE clients for real-time event streaming.\n */\n\nexport * from \"./types.js\";\nexport { WebSocketRealtimeClient } from \"./websocket.js\";\nexport { SseRealtimeClient } from \"./sse.js\";\n\nimport { WebSocketRealtimeClient } from \"./websocket.js\";\nimport { SseRealtimeClient } from \"./sse.js\";\nimport type {\n RealtimeConnectionOptions,\n RealtimeEvent,\n RealtimeEventType,\n SubscriptionFilter,\n ConnectionState,\n} from \"./types.js\";\n\n/** Options for creating a SpooledRealtime instance */\nexport interface SpooledRealtimeOptions {\n /**\n * Connection type: 'websocket' or 'sse' (default: 'websocket').\n *\n * Default is WebSocket because it’s typically the lowest server load:\n * - WebSocket uses push/pubsub in the backend\n * - SSE job/queue endpoints poll the database periodically\n */\n type?: \"websocket\" | \"sse\";\n /** Auto-reconnect on disconnect (default: true) */\n autoReconnect?: boolean;\n /** Maximum reconnect attempts (default: 10) */\n maxReconnectAttempts?: number;\n /** Initial reconnect delay in ms (default: 1000) */\n reconnectDelay?: number;\n /** Maximum reconnect delay in ms (default: 30000) */\n maxReconnectDelay?: number;\n}\n\n/** Full options including internal fields */\ninterface FullRealtimeOptions extends SpooledRealtimeOptions {\n baseUrl: string;\n wsUrl: string;\n token: string;\n /** Async provider that supplies a valid JWT for each (re)connect */\n tokenProvider?: (forceRefresh?: boolean) => Promise<string>;\n debug?: (message: string, meta?: unknown) => void;\n}\n\n/** Event handler type - simplified for internal use */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EventHandler = (data: any) => void;\n\n/** Generic event handler */\ntype GenericEventHandler = (event: RealtimeEvent) => void;\n\n/**\n * Unified Realtime Client\n *\n * Wraps WebSocket and SSE clients with a common interface.\n */\nexport class SpooledRealtime {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private readonly client: any;\n\n constructor(options: FullRealtimeOptions) {\n const connectionOptions: RealtimeConnectionOptions = {\n baseUrl: options.baseUrl,\n wsUrl: options.wsUrl,\n token: options.token,\n tokenProvider: options.tokenProvider,\n autoReconnect: options.autoReconnect,\n maxReconnectAttempts: options.maxReconnectAttempts,\n reconnectDelay: options.reconnectDelay,\n maxReconnectDelay: options.maxReconnectDelay,\n debug: options.debug,\n };\n\n if (options.type === \"sse\") {\n this.client = new SseRealtimeClient(connectionOptions);\n } else {\n this.client = new WebSocketRealtimeClient(connectionOptions);\n }\n }\n\n /**\n * Get current connection state\n */\n getState(): ConnectionState {\n return this.client.getState();\n }\n\n /**\n * Connect to the realtime server\n */\n async connect(): Promise<void> {\n return this.client.connect();\n }\n\n /**\n * Disconnect from the realtime server\n */\n disconnect(): void {\n this.client.disconnect();\n }\n\n /**\n * Subscribe to events matching a filter\n *\n * @example\n * ```typescript\n * // Subscribe to all events from a queue\n * await realtime.subscribe({ queueName: 'my-queue' });\n *\n * // Subscribe to events for a specific job\n * await realtime.subscribe({ jobId: 'job-123' });\n * ```\n */\n async subscribe(filter: SubscriptionFilter): Promise<void> {\n // SSE subscriptions are effectively endpoint-based; change requires reconnect.\n if (typeof this.client.subscribe === \"function\") {\n return this.client.subscribe(filter);\n }\n return this.client.reconnect(filter);\n }\n\n /**\n * Unsubscribe from events matching a filter\n */\n async unsubscribe(filter: SubscriptionFilter): Promise<void> {\n if (typeof this.client.unsubscribe === \"function\") {\n return this.client.unsubscribe(filter);\n }\n // For SSE, unsubscribing means disconnecting if the filter matches current connection.\n this.client.disconnect();\n }\n\n /**\n * Add an event listener for a specific event type\n *\n * @example\n * ```typescript\n * realtime.on('job.completed', (data) => {\n * console.log('Job completed:', data.jobId);\n * });\n *\n * realtime.on('job.failed', (data) => {\n * console.error('Job failed:', data.error);\n * });\n * ```\n */\n on<T extends RealtimeEventType>(type: T, handler: EventHandler): () => void {\n return this.client.on(type, handler);\n }\n\n /**\n * Remove an event listener\n */\n off<T extends RealtimeEventType>(type: T, handler: EventHandler): void {\n this.client.off(type, handler);\n }\n\n /**\n * Add a listener for all events\n *\n * @example\n * ```typescript\n * realtime.onEvent((event) => {\n * console.log(`Event: ${event.type}`, event.data);\n * });\n * ```\n */\n onEvent(handler: GenericEventHandler): () => void {\n return this.client.onEvent(handler);\n }\n\n /**\n * Add a listener for connection state changes\n *\n * @example\n * ```typescript\n * realtime.onStateChange((state) => {\n * console.log('Connection state:', state);\n * });\n * ```\n */\n onStateChange(handler: (state: ConnectionState) => void): () => void {\n return this.client.onStateChange(handler);\n }\n}\n","/**\n * Proto Loader Utility\n *\n * Dynamically loads the Spooled proto file for gRPC communication.\n */\n\n/* global __dirname */\n\nimport * as grpc from \"@grpc/grpc-js\";\nimport * as protoLoader from \"@grpc/proto-loader\";\nimport { existsSync } from \"fs\";\nimport { fileURLToPath } from \"url\";\nimport { dirname, join } from \"path\";\nimport type { ServiceClientConstructor } from \"@grpc/grpc-js\";\n\n/** Proto loader options for consistent parsing */\nexport const PROTO_LOADER_OPTIONS: protoLoader.Options = {\n keepCase: false, // Convert snake_case to camelCase\n longs: String, // Represent int64 as strings\n enums: String, // Represent enums as strings\n defaults: true, // Include default values\n oneofs: true, // Support oneofs\n};\n\nexport interface SpooledProtoDefinition {\n spooled: {\n v1: {\n QueueService: ServiceClientConstructor;\n WorkerService: ServiceClientConstructor;\n };\n };\n}\n\nlet cachedDefinition: SpooledProtoDefinition | null = null;\n\n/**\n * Resolve the directory that contains this module (ESM or CJS).\n */\nfunction getModuleDir(): string {\n if (typeof import.meta?.url !== \"undefined\") {\n return dirname(fileURLToPath(import.meta.url));\n }\n return __dirname;\n}\n\n/**\n * Get the path to the proto file.\n *\n * tsup bundles `src/grpc/loader.ts` into `dist/index.js`, so a single\n * `../../proto` relative path (correct from `src/grpc/`) resolves one level\n * above the package root from `dist/` and breaks gRPC client construction.\n * Try both layouts (plus package-root fallbacks) and pick the first hit.\n */\nexport function getProtoPath(): string {\n const moduleDir = getModuleDir();\n const candidates = [\n // Bundled ESM/CJS: dist/index.js → ../proto/spooled.proto\n join(moduleDir, \"../proto/spooled.proto\"),\n // Source / unbundled: src/grpc/loader.ts → ../../proto/spooled.proto\n join(moduleDir, \"../../proto/spooled.proto\"),\n // Extra safety if moduleDir is package root\n join(moduleDir, \"proto/spooled.proto\"),\n ];\n\n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n\n throw new Error(\n `Spooled gRPC proto not found. Tried: ${candidates.join(\", \")}. ` +\n `Ensure the package's proto/spooled.proto is installed next to dist/.`,\n );\n}\n\n/**\n * Load the Spooled proto definition synchronously.\n * Caches the result for subsequent calls.\n */\nexport function loadProtoDefinition(): SpooledProtoDefinition {\n if (cachedDefinition) {\n return cachedDefinition;\n }\n\n const protoPath = getProtoPath();\n\n const packageDefinition = protoLoader.loadSync(\n protoPath,\n PROTO_LOADER_OPTIONS,\n );\n const grpcObject = grpc.loadPackageDefinition(packageDefinition);\n\n cachedDefinition = grpcObject as unknown as SpooledProtoDefinition;\n return cachedDefinition;\n}\n\n/**\n * Load the Spooled proto definition asynchronously.\n */\nexport async function loadProtoDefinitionAsync(): Promise<SpooledProtoDefinition> {\n if (cachedDefinition) {\n return cachedDefinition;\n }\n\n const protoPath = getProtoPath();\n\n const packageDefinition = await protoLoader.load(\n protoPath,\n PROTO_LOADER_OPTIONS,\n );\n const grpcObject = grpc.loadPackageDefinition(packageDefinition);\n\n cachedDefinition = grpcObject as unknown as SpooledProtoDefinition;\n return cachedDefinition;\n}\n\n/**\n * Clear the cached proto definition (mainly for testing).\n */\nexport function clearProtoCache(): void {\n cachedDefinition = null;\n}\n","/**\n * gRPC message encoding and decoding shared by the unary client and the\n * StreamJobs / ProcessJobs streams.\n */\n\nimport type {\n GrpcCompleteRequest,\n GrpcEnqueueRequest,\n GrpcFailRequest,\n GrpcJob,\n GrpcProcessRequest,\n GrpcProcessResponse,\n} from \"./types.js\";\n\n/**\n * Default `retry` to true (callers opt out with an explicit `retry: false`).\n *\n * The proto declares `optional bool retry = 4`, so an explicit `false` goes on\n * the wire with presence and dead-letters the job now, and `true` retries it\n * until its `maxRetries` run out. The default is sent explicitly rather than\n * left off: servers before API 0.1.118 declared a plain `bool`, read an absent\n * field as `false` and dead-lettered the job on its first failure.\n */\nexport function encodeFailRequest(params: GrpcFailRequest): GrpcFailRequest {\n return { ...params, retry: params.retry ?? true };\n}\n\ntype ProtobufValue =\n | { nullValue: 0 }\n | { numberValue: number }\n | { stringValue: string }\n | { boolValue: boolean }\n | { structValue: ProtobufStruct }\n | { listValue: { values: ProtobufValue[] } };\n\ninterface ProtobufStruct {\n fields: Record<string, ProtobufValue>;\n}\n\nfunction encodeStruct(\n value: Record<string, unknown> | null | undefined,\n): ProtobufStruct | undefined {\n if (value == null) {\n return undefined;\n }\n return {\n fields: Object.fromEntries(\n Object.entries(value).map(([key, entry]) => [key, encodeValue(entry)]),\n ),\n };\n}\n\nfunction encodeValue(value: unknown): ProtobufValue {\n if (value == null) {\n return { nullValue: 0 };\n }\n if (Array.isArray(value)) {\n return { listValue: { values: value.map(encodeValue) } };\n }\n switch (typeof value) {\n case \"number\":\n return { numberValue: value };\n case \"string\":\n return { stringValue: value };\n case \"boolean\":\n return { boolValue: value };\n case \"object\":\n return { structValue: encodeStruct(value as Record<string, unknown>)! };\n default:\n return { stringValue: String(value) };\n }\n}\n\nfunction decodeStruct(\n value: unknown,\n): Record<string, unknown> | null | undefined {\n if (!value || typeof value !== \"object\" || !(\"fields\" in value)) {\n return value as Record<string, unknown> | null | undefined;\n }\n const fields = (value as ProtobufStruct).fields ?? {};\n return Object.fromEntries(\n Object.entries(fields).map(([key, entry]) => [key, decodeValue(entry)]),\n );\n}\n\nfunction decodeValue(value: ProtobufValue): unknown {\n if (\"nullValue\" in value) {\n return null;\n }\n if (\"numberValue\" in value) {\n return value.numberValue;\n }\n if (\"stringValue\" in value) {\n return value.stringValue;\n }\n if (\"boolValue\" in value) {\n return value.boolValue;\n }\n if (\"structValue\" in value) {\n return decodeStruct(value.structValue);\n }\n if (\"listValue\" in value) {\n return (value.listValue.values ?? []).map(decodeValue);\n }\n return undefined;\n}\n\nexport function encodeEnqueueRequest(\n params: GrpcEnqueueRequest,\n): GrpcEnqueueRequest {\n // Omit unset numeric fields so proto-loader `defaults: true` does not force\n // wire zeros for maxRetries/timeoutSeconds (server treats 0 as its default).\n const encoded: Record<string, unknown> = {\n queueName: params.queueName,\n payload: encodeStruct(params.payload),\n };\n if (params.priority !== undefined) {\n encoded.priority = params.priority;\n }\n if (params.maxRetries !== undefined) {\n encoded.maxRetries = params.maxRetries;\n }\n if (params.timeoutSeconds !== undefined) {\n encoded.timeoutSeconds = params.timeoutSeconds;\n }\n if (params.idempotencyKey !== undefined && params.idempotencyKey !== \"\") {\n encoded.idempotencyKey = params.idempotencyKey;\n }\n if (params.scheduledAt !== undefined) {\n encoded.scheduledAt = params.scheduledAt;\n }\n if (params.tags !== undefined) {\n encoded.tags = params.tags;\n }\n return encoded as unknown as GrpcEnqueueRequest;\n}\n\nexport function encodeCompleteRequest(\n params: GrpcCompleteRequest,\n): GrpcCompleteRequest {\n return {\n ...params,\n result: encodeStruct(params.result) as unknown as Record<string, unknown>,\n };\n}\n\nexport function decodeJob(job: GrpcJob): GrpcJob {\n return {\n ...job,\n // proto-loader keeps an enum number it does not know (a status added to\n // the server's proto after this SDK) as a number; keep it a string so\n // `status` always matches its type.\n status: typeof job.status === \"number\" ? String(job.status) : job.status,\n payload: decodeStruct(job.payload),\n result: decodeStruct(job.result),\n };\n}\n\n/**\n * Encode a ProcessJobs request: a `fail` gets the `retry` default and a\n * `complete` its `result` as a `google.protobuf.Struct`, as on the unary calls.\n */\nexport function encodeProcessRequest(\n request: GrpcProcessRequest,\n): GrpcProcessRequest {\n if (request.fail) {\n return { ...request, fail: encodeFailRequest(request.fail) };\n }\n if (request.complete) {\n return { ...request, complete: encodeCompleteRequest(request.complete) };\n }\n return request;\n}\n\n/** Decode a ProcessJobs response: its `job` like a unary Dequeue job. */\nexport function decodeProcessResponse(\n response: GrpcProcessResponse,\n): GrpcProcessResponse {\n return response.job\n ? { ...response, job: decodeJob(response.job) }\n : response;\n}\n","/**\n * gRPC Streaming Helpers\n *\n * Utilities for working with gRPC streaming in a TypeScript-friendly way.\n */\n\nimport type * as grpc from \"@grpc/grpc-js\";\nimport {\n decodeJob,\n decodeProcessResponse,\n encodeProcessRequest,\n} from \"./encode.js\";\nimport type {\n GrpcJob,\n GrpcProcessRequest,\n GrpcProcessResponse,\n} from \"./types.js\";\n\n/**\n * Options for streaming operations\n */\nexport interface StreamOptions {\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n /** Called when connection is established */\n onConnected?: () => void;\n /** Called when an error occurs */\n onError?: (error: Error) => void;\n /** Called when the stream ends */\n onEnd?: () => void;\n}\n\n/**\n * Async iterable wrapper for gRPC readable streams (server streaming).\n */\nexport async function* asyncIterableFromStream<T>(\n stream: grpc.ClientReadableStream<T>,\n options?: StreamOptions,\n): AsyncGenerator<T, void, undefined> {\n const { signal, onConnected, onError, onEnd } = options ?? {};\n\n // Handle abort signal\n if (signal) {\n signal.addEventListener(\"abort\", () => {\n stream.cancel();\n });\n }\n\n return yield* new AsyncIterableStream(stream, {\n onConnected,\n onError,\n onEnd,\n });\n}\n\n/**\n * AsyncIterable wrapper for grpc.ClientReadableStream\n */\nclass AsyncIterableStream<T> implements AsyncIterable<T> {\n private stream: grpc.ClientReadableStream<T>;\n private options: Omit<StreamOptions, \"signal\">;\n private readonly decode: (item: T) => T;\n\n constructor(\n stream: grpc.ClientReadableStream<T>,\n options: Omit<StreamOptions, \"signal\"> = {},\n decode: (item: T) => T = (item) => item,\n ) {\n this.stream = stream;\n this.options = options;\n this.decode = decode;\n }\n\n async *[Symbol.asyncIterator](): AsyncGenerator<T, void, undefined> {\n const { onConnected, onError, onEnd } = this.options;\n const queue: T[] = [];\n let error: Error | null = null;\n let ended = false;\n let decodeFailed = false;\n let resolve: (() => void) | null = null;\n\n this.stream.on(\"data\", (data: T) => {\n // After a decode failure the stream is being cancelled; what the server\n // still has in flight is dropped, so no item is yielded out of order.\n if (decodeFailed) {\n return;\n }\n try {\n queue.push(this.decode(data));\n } catch (decodeError) {\n decodeFailed = true;\n error =\n decodeError instanceof Error\n ? decodeError\n : new Error(String(decodeError));\n // The iteration ends with this error, so stop the call instead of\n // leaving it open and receiving jobs nobody reads.\n try {\n this.stream.cancel?.();\n } catch {\n // The decode error is the one to report.\n }\n }\n resolve?.();\n });\n\n this.stream.on(\"error\", (err: Error) => {\n // The CANCELLED error our own cancel() causes must not replace the\n // decode error or reach onError.\n if (decodeFailed) {\n return;\n }\n error = err;\n onError?.(err);\n resolve?.();\n });\n\n this.stream.on(\"end\", () => {\n ended = true;\n onEnd?.();\n resolve?.();\n });\n\n this.stream.on(\"status\", (status: grpc.StatusObject) => {\n if (status.code === 0) {\n onConnected?.();\n }\n });\n\n while (true) {\n if (queue.length > 0) {\n yield queue.shift()!;\n continue;\n }\n\n if (error) {\n throw error;\n }\n\n if (ended) {\n return;\n }\n\n // Wait for next event\n await new Promise<void>((r) => {\n resolve = r;\n });\n }\n }\n}\n\n/**\n * Bidirectional stream wrapper for ProcessJobs\n */\nexport interface ProcessJobsStream {\n /** Send a request to the server */\n send(request: GrpcProcessRequest): void;\n /** Get async iterable for receiving responses */\n receive(): AsyncIterable<GrpcProcessResponse>;\n /** Signal that no more requests will be sent */\n end(): void;\n /** Cancel the stream */\n cancel(): void;\n}\n\n/**\n * Create a ProcessJobsStream from a gRPC duplex stream\n */\nexport function createProcessJobsStream(\n call: grpc.ClientDuplexStream<GrpcProcessRequest, GrpcProcessResponse>,\n options?: StreamOptions,\n): ProcessJobsStream {\n const { signal, onError, onEnd } = options ?? {};\n\n // Handle abort signal\n if (signal) {\n signal.addEventListener(\"abort\", () => {\n call.cancel();\n });\n }\n\n return {\n send(request: GrpcProcessRequest): void {\n call.write(encodeProcessRequest(request));\n },\n\n receive(): AsyncIterable<GrpcProcessResponse> {\n return new AsyncIterableStream(\n call,\n { onError, onEnd },\n decodeProcessResponse,\n );\n },\n\n end(): void {\n call.end();\n },\n\n cancel(): void {\n call.cancel();\n },\n };\n}\n\n/**\n * Job stream for server-side streaming (StreamJobs)\n */\nexport interface JobStream extends AsyncIterable<GrpcJob> {\n /** Cancel the stream */\n cancel(): void;\n}\n\n/**\n * Create a JobStream from a gRPC server stream\n */\nexport function createJobStream(\n call: grpc.ClientReadableStream<GrpcJob>,\n options?: StreamOptions,\n): JobStream {\n const { signal, onConnected, onError, onEnd } = options ?? {};\n\n // Handle abort signal\n if (signal) {\n signal.addEventListener(\"abort\", () => {\n call.cancel();\n });\n }\n\n const iterable = new AsyncIterableStream<GrpcJob>(\n call,\n { onConnected, onError, onEnd },\n decodeJob,\n );\n\n return {\n [Symbol.asyncIterator]() {\n return iterable[Symbol.asyncIterator]();\n },\n cancel() {\n call.cancel();\n },\n };\n}\n","/**\n * gRPC Client\n *\n * Real gRPC client using @grpc/grpc-js for HTTP/2 + Protobuf communication.\n * Supports unary calls, server streaming, and bidirectional streaming.\n */\n\nimport * as grpc from \"@grpc/grpc-js\";\nimport { loadProtoDefinition } from \"./loader.js\";\nimport {\n decodeJob,\n encodeCompleteRequest,\n encodeEnqueueRequest,\n encodeFailRequest,\n} from \"./encode.js\";\nimport {\n createJobStream,\n createProcessJobsStream,\n type JobStream,\n type ProcessJobsStream,\n type StreamOptions,\n} from \"./streaming.js\";\nimport type {\n GrpcClientOptions,\n GrpcEnqueueRequest,\n GrpcEnqueueResponse,\n GrpcDequeueRequest,\n GrpcDequeueResponse,\n GrpcCompleteRequest,\n GrpcCompleteResponse,\n GrpcFailRequest,\n GrpcFailResponse,\n GrpcRenewLeaseRequest,\n GrpcRenewLeaseResponse,\n GrpcGetJobRequest,\n GrpcGetJobResponse,\n GrpcGetQueueStatsRequest,\n GrpcGetQueueStatsResponse,\n GrpcStreamJobsRequest,\n GrpcRegisterWorkerRequest,\n GrpcRegisterWorkerResponse,\n GrpcHeartbeatRequest,\n GrpcHeartbeatResponse,\n GrpcDeregisterRequest,\n GrpcDeregisterResponse,\n GrpcProcessRequest,\n GrpcProcessResponse,\n GrpcJob,\n} from \"./types.js\";\nimport {\n AuthenticationError,\n AuthorizationError,\n ConflictError,\n NetworkError,\n NotFoundError,\n RateLimitError,\n ServerError,\n TimeoutError,\n ValidationError,\n} from \"../errors.js\";\n\n// Type definitions for dynamic gRPC clients\ntype UnaryCallback<T> = (error: grpc.ServiceError | null, response: T) => void;\ntype UnaryMethod<TReq, TRes> = {\n (request: TReq, metadata: grpc.Metadata, callback: UnaryCallback<TRes>): void;\n (\n request: TReq,\n metadata: grpc.Metadata,\n options: grpc.CallOptions,\n callback: UnaryCallback<TRes>,\n ): void;\n};\n\ninterface QueueServiceClient extends grpc.Client {\n Enqueue: UnaryMethod<GrpcEnqueueRequest, GrpcEnqueueResponse>;\n Dequeue: UnaryMethod<GrpcDequeueRequest, GrpcDequeueResponse>;\n Complete: UnaryMethod<GrpcCompleteRequest, GrpcCompleteResponse>;\n Fail: UnaryMethod<GrpcFailRequest, GrpcFailResponse>;\n RenewLease: UnaryMethod<GrpcRenewLeaseRequest, GrpcRenewLeaseResponse>;\n GetJob: UnaryMethod<GrpcGetJobRequest, GrpcGetJobResponse>;\n GetQueueStats: UnaryMethod<\n GrpcGetQueueStatsRequest,\n GrpcGetQueueStatsResponse\n >;\n StreamJobs(\n request: GrpcStreamJobsRequest,\n metadata: grpc.Metadata,\n ): grpc.ClientReadableStream<GrpcJob>;\n ProcessJobs(\n metadata: grpc.Metadata,\n ): grpc.ClientDuplexStream<GrpcProcessRequest, GrpcProcessResponse>;\n}\n\ninterface WorkerServiceClient extends grpc.Client {\n Register: UnaryMethod<GrpcRegisterWorkerRequest, GrpcRegisterWorkerResponse>;\n Heartbeat: UnaryMethod<GrpcHeartbeatRequest, GrpcHeartbeatResponse>;\n Deregister: UnaryMethod<GrpcDeregisterRequest, GrpcDeregisterResponse>;\n}\n\n/**\n * Wrap a callback-based gRPC call in a Promise\n */\nfunction promisify<TReq, TRes>(\n client: grpc.Client,\n method: UnaryMethod<TReq, TRes>,\n request: TReq,\n metadata: grpc.Metadata,\n timeoutMs?: number,\n): Promise<TRes> {\n return new Promise((resolve, reject) => {\n const callback: UnaryCallback<TRes> = (error, response) => {\n if (error) {\n reject(mapGrpcError(error, timeoutMs));\n } else {\n resolve(response);\n }\n };\n\n method.call(\n client,\n request,\n metadata,\n createUnaryCallOptions(timeoutMs),\n callback,\n );\n });\n}\n\nfunction createUnaryCallOptions(timeoutMs?: number): grpc.CallOptions {\n if (timeoutMs === undefined) {\n return {};\n }\n return { deadline: new Date(Date.now() + timeoutMs) };\n}\n\nfunction mapGrpcError(error: grpc.ServiceError, timeoutMs?: number): Error {\n const message = error.details || error.message || \"gRPC request failed\";\n\n switch (error.code) {\n case grpc.status.DEADLINE_EXCEEDED:\n return new TimeoutError(message, timeoutMs ?? 0);\n case grpc.status.UNAUTHENTICATED:\n return new AuthenticationError(message, \"AUTHENTICATION_FAILED\");\n case grpc.status.PERMISSION_DENIED:\n return new AuthorizationError(message, \"ACCESS_DENIED\");\n case grpc.status.NOT_FOUND:\n return new NotFoundError(message, \"NOT_FOUND\");\n case grpc.status.INVALID_ARGUMENT:\n case grpc.status.OUT_OF_RANGE:\n return new ValidationError(message, \"VALIDATION_ERROR\");\n case grpc.status.ALREADY_EXISTS:\n case grpc.status.ABORTED:\n case grpc.status.FAILED_PRECONDITION:\n return new ConflictError(message, \"CONFLICT\");\n case grpc.status.RESOURCE_EXHAUSTED:\n return new RateLimitError(message, \"RATE_LIMIT_EXCEEDED\");\n case grpc.status.UNAVAILABLE:\n case grpc.status.CANCELLED:\n return new NetworkError(message, error);\n default:\n if (error.code >= grpc.status.INTERNAL) {\n return new ServerError(message, 500, \"GRPC_SERVER_ERROR\");\n }\n return new ServerError(message, 500, \"GRPC_ERROR\");\n }\n}\n\n/** Host part of a `host:port` address, including bracketed IPv6 (`[::1]:50051`). */\nfunction grpcHost(address: string): string {\n if (address.startsWith(\"[\")) {\n const end = address.indexOf(\"]\");\n return end === -1 ? address : address.slice(1, end);\n }\n // A bare IPv6 literal has several colons and no port to strip.\n return address.split(\":\").length > 2 ? address : address.split(\":\")[0];\n}\n\n/**\n * Determine if TLS should be used based on address\n */\nfunction shouldUseTls(address: string, explicitTls?: boolean): boolean {\n if (explicitTls !== undefined) {\n return explicitTls;\n }\n // Default to insecure for localhost/127.0.0.1\n const host = grpcHost(address).toLowerCase();\n return host !== \"localhost\" && host !== \"127.0.0.1\" && host !== \"::1\";\n}\n\n/**\n * Queue operations for the gRPC client\n */\nexport class GrpcQueueOperations {\n constructor(\n private readonly client: QueueServiceClient,\n private readonly metadata: grpc.Metadata,\n private readonly timeoutMs?: number,\n ) {}\n\n /**\n * Enqueue a new job\n */\n async enqueue(params: GrpcEnqueueRequest): Promise<GrpcEnqueueResponse> {\n return promisify(\n this.client,\n this.client.Enqueue,\n encodeEnqueueRequest(params),\n this.metadata,\n this.timeoutMs,\n );\n }\n\n /**\n * Dequeue a job (for workers)\n */\n async dequeue(params: GrpcDequeueRequest): Promise<GrpcDequeueResponse> {\n const response = await promisify(\n this.client,\n this.client.Dequeue,\n params,\n this.metadata,\n this.timeoutMs,\n );\n return { ...response, jobs: response.jobs.map(decodeJob) };\n }\n\n /**\n * Complete a job successfully\n */\n async complete(params: GrpcCompleteRequest): Promise<GrpcCompleteResponse> {\n return promisify(\n this.client,\n this.client.Complete,\n encodeCompleteRequest(params),\n this.metadata,\n this.timeoutMs,\n );\n }\n\n /**\n * Fail a job\n */\n async fail(params: GrpcFailRequest): Promise<GrpcFailResponse> {\n return promisify(\n this.client,\n this.client.Fail,\n encodeFailRequest(params),\n this.metadata,\n this.timeoutMs,\n );\n }\n\n /**\n * Renew a job's lease\n */\n async renewLease(\n params: GrpcRenewLeaseRequest,\n ): Promise<GrpcRenewLeaseResponse> {\n return promisify(\n this.client,\n this.client.RenewLease,\n params,\n this.metadata,\n this.timeoutMs,\n );\n }\n\n /**\n * Get a job by ID\n */\n async getJob(jobId: string): Promise<GrpcGetJobResponse> {\n const response = await promisify(\n this.client,\n this.client.GetJob,\n { jobId },\n this.metadata,\n this.timeoutMs,\n );\n return {\n ...response,\n job: response.job ? decodeJob(response.job) : response.job,\n };\n }\n\n /**\n * Get queue statistics\n */\n async getQueueStats(queueName: string): Promise<GrpcGetQueueStatsResponse> {\n return promisify(\n this.client,\n this.client.GetQueueStats,\n { queueName },\n this.metadata,\n this.timeoutMs,\n );\n }\n\n /**\n * Stream jobs from a queue (server-side streaming)\n *\n * @example\n * ```typescript\n * const stream = client.grpc.queue.streamJobs({\n * queueName: 'my-queue',\n * workerId: 'worker-1',\n * });\n *\n * for await (const job of stream) {\n * console.log('Received job:', job.id);\n * }\n * ```\n */\n streamJobs(\n params: GrpcStreamJobsRequest,\n options?: StreamOptions,\n ): JobStream {\n const call = this.client.StreamJobs(params, this.metadata);\n return createJobStream(call, options);\n }\n\n /**\n * Open a bidirectional stream for processing jobs\n *\n * @example\n * ```typescript\n * const stream = client.grpc.queue.processJobs();\n *\n * // Request jobs\n * stream.send({ dequeue: { queueName: 'my-queue', workerId: 'worker-1' } });\n *\n * // Process responses\n * for await (const response of stream.receive()) {\n * if (response.job) {\n * // Process the job\n * stream.send({ complete: { jobId: response.job.id, workerId: 'worker-1' } });\n * }\n * }\n *\n * stream.end();\n * ```\n */\n processJobs(options?: StreamOptions): ProcessJobsStream {\n const call = this.client.ProcessJobs(this.metadata);\n return createProcessJobsStream(call, options);\n }\n}\n\n/**\n * Worker operations for the gRPC client\n */\nexport class GrpcWorkerOperations {\n constructor(\n private readonly client: WorkerServiceClient,\n private readonly metadata: grpc.Metadata,\n private readonly timeoutMs?: number,\n ) {}\n\n /**\n * Register a new worker\n */\n async register(\n params: GrpcRegisterWorkerRequest,\n ): Promise<GrpcRegisterWorkerResponse> {\n return promisify(\n this.client,\n this.client.Register,\n params,\n this.metadata,\n this.timeoutMs,\n );\n }\n\n /**\n * Send heartbeat\n */\n async heartbeat(\n params: GrpcHeartbeatRequest,\n ): Promise<GrpcHeartbeatResponse> {\n return promisify(\n this.client,\n this.client.Heartbeat,\n params,\n this.metadata,\n this.timeoutMs,\n );\n }\n\n /**\n * Deregister a worker\n */\n async deregister(workerId: string): Promise<GrpcDeregisterResponse> {\n return promisify(\n this.client,\n this.client.Deregister,\n { workerId },\n this.metadata,\n this.timeoutMs,\n );\n }\n}\n\n/**\n * Spooled gRPC Client\n *\n * Real gRPC client for high-performance job queue operations.\n *\n * @example\n * ```typescript\n * const client = new SpooledGrpcClient({\n * address: 'grpc.spooled.cloud:443',\n * apiKey: 'sk_live_...',\n * });\n *\n * // Enqueue a job\n * const { jobId } = await client.queue.enqueue({\n * queueName: 'my-queue',\n * payload: { message: 'Hello!' },\n * });\n *\n * // Stream jobs\n * for await (const job of client.queue.streamJobs({\n * queueName: 'my-queue',\n * workerId: 'worker-1',\n * })) {\n * console.log('Job:', job);\n * }\n * ```\n */\nexport class SpooledGrpcClient {\n private readonly queueClient: QueueServiceClient;\n private readonly workerClient: WorkerServiceClient;\n private readonly metadata: grpc.Metadata;\n\n /** Queue operations */\n readonly queue: GrpcQueueOperations;\n\n /** Worker operations */\n readonly workers: GrpcWorkerOperations;\n\n constructor(options: GrpcClientOptions) {\n const { address, apiKey, useTls, credentials, channelOptions, timeout } =\n options;\n\n // Create credentials\n const creds =\n credentials ??\n (shouldUseTls(address, useTls)\n ? grpc.credentials.createSsl()\n : grpc.credentials.createInsecure());\n\n // Create metadata with API key\n this.metadata = new grpc.Metadata();\n this.metadata.add(\"x-api-key\", apiKey);\n\n // Load proto definition\n const proto = loadProtoDefinition();\n\n // Create service clients\n this.queueClient = new proto.spooled.v1.QueueService(\n address,\n creds,\n channelOptions,\n ) as unknown as QueueServiceClient;\n\n this.workerClient = new proto.spooled.v1.WorkerService(\n address,\n creds,\n channelOptions,\n ) as unknown as WorkerServiceClient;\n\n // Initialize operation namespaces\n this.queue = new GrpcQueueOperations(\n this.queueClient,\n this.metadata,\n timeout,\n );\n this.workers = new GrpcWorkerOperations(\n this.workerClient,\n this.metadata,\n timeout,\n );\n }\n\n /**\n * Close all gRPC connections\n */\n close(): void {\n this.queueClient.close();\n this.workerClient.close();\n }\n\n /**\n * Wait for the clients to be ready\n */\n async waitForReady(deadline?: Date): Promise<void> {\n const d = deadline ?? new Date(Date.now() + 10000);\n await Promise.all([\n new Promise<void>((resolve, reject) => {\n this.queueClient.waitForReady(d, (error) => {\n if (error) reject(error);\n else resolve();\n });\n }),\n new Promise<void>((resolve, reject) => {\n this.workerClient.waitForReady(d, (error) => {\n if (error) reject(error);\n else resolve();\n });\n }),\n ]);\n }\n\n /**\n * Get the current connection state\n */\n getState(tryToConnect?: boolean): grpc.connectivityState {\n return this.queueClient\n .getChannel()\n .getConnectivityState(tryToConnect ?? false);\n }\n}\n","/**\n * Spooled Client\n *\n * Main entry point for the Spooled SDK.\n */\n\nimport {\n type SpooledClientConfig,\n type ResolvedConfig,\n resolveConfig,\n validateConfig,\n} from \"./config.js\";\nimport { AuthenticationError, type RateLimitInfo } from \"./errors.js\";\nimport { HttpClient, createHttpClient } from \"./utils/http.js\";\nimport {\n CircuitBreaker,\n createCircuitBreaker,\n} from \"./utils/circuit-breaker.js\";\nimport {\n AuthResource,\n JobsResource,\n QueuesResource,\n WorkersResource,\n SchedulesResource,\n WorkflowsResource,\n WebhooksResource,\n ApiKeysResource,\n OrganizationsResource,\n BillingResource,\n DashboardResource,\n HealthResource,\n MetricsResource,\n AdminResource,\n WebhookIngestionResource,\n} from \"./resources/index.js\";\nimport { SpooledRealtime } from \"./realtime/index.js\";\nimport type { SpooledRealtimeOptions } from \"./realtime/index.js\";\nimport { SpooledGrpcClient } from \"./grpc/client.js\";\n\n/**\n * Spooled Cloud SDK Client\n *\n * @example\n * ```typescript\n * const client = new SpooledClient({\n * apiKey: 'sk_live_...'\n * });\n *\n * // Create a job\n * const result = await client.jobs.create({\n * queueName: 'my-queue',\n * payload: { message: 'Hello, World!' }\n * });\n *\n * // List queues\n * const queues = await client.queues.list();\n * ```\n */\nexport class SpooledClient {\n private readonly config: ResolvedConfig;\n private readonly http: HttpClient;\n private readonly circuitBreaker: CircuitBreaker;\n private _grpc: SpooledGrpcClient | null = null;\n\n /** Authentication operations */\n readonly auth: AuthResource;\n\n /** Job operations */\n readonly jobs: JobsResource;\n\n /** Queue operations */\n readonly queues: QueuesResource;\n\n /** Worker operations */\n readonly workers: WorkersResource;\n\n /** Schedule operations */\n readonly schedules: SchedulesResource;\n\n /** Workflow operations */\n readonly workflows: WorkflowsResource;\n\n /** Outgoing webhook operations */\n readonly webhooks: WebhooksResource;\n\n /** API key operations */\n readonly apiKeys: ApiKeysResource;\n\n /** Organization operations */\n readonly organizations: OrganizationsResource;\n\n /** Billing operations */\n readonly billing: BillingResource;\n\n /** Dashboard operations */\n readonly dashboard: DashboardResource;\n\n /** Health endpoints (public) */\n readonly health: HealthResource;\n\n /** Metrics endpoint (public) */\n readonly metrics: MetricsResource;\n\n /** Admin endpoints (requires adminKey) */\n readonly admin: AdminResource;\n\n /** Webhook ingestion endpoints (signature-based) */\n readonly ingest: WebhookIngestionResource;\n\n /** Token refresh state */\n private refreshPromise: Promise<string> | null = null;\n private tokenExpiresAt: number | null = null;\n\n /**\n * Cached JWT for realtime connections (API-key auth path).\n *\n * The realtime layer requests a token on every (re)connect. Minting a brand\n * new JWT via POST /auth/login each time trips the login rate limit (429)\n * under a reconnect storm, after which realtime can never recover. We cache\n * the token here — at the client level, shared across reconnects — and reuse\n * it until it nears expiry.\n */\n private cachedJwt: string | null = null;\n /** Deduplicates concurrent logins (e.g. WS + SSE reconnecting together). */\n private jwtLoginPromise: Promise<string> | null = null;\n\n constructor(options: SpooledClientConfig) {\n // Resolve and validate configuration\n this.config = resolveConfig(options);\n validateConfig(this.config);\n\n // Create circuit breaker\n this.circuitBreaker = createCircuitBreaker(this.config.circuitBreaker);\n\n // Create HTTP client\n this.http = createHttpClient(this.config, this.circuitBreaker);\n\n // Set up token refresh if using JWT\n if (\n this.config.accessToken &&\n this.config.refreshToken &&\n this.config.autoRefreshToken\n ) {\n this.http.setRefreshTokenFn(this.refreshAccessToken.bind(this));\n }\n\n // Create resource instances\n this.auth = new AuthResource(this.http, () => this.config.refreshToken);\n this.jobs = new JobsResource(this.http);\n this.queues = new QueuesResource(this.http);\n this.workers = new WorkersResource(this.http);\n this.schedules = new SchedulesResource(this.http);\n this.workflows = new WorkflowsResource(this.http);\n this.webhooks = new WebhooksResource(this.http);\n this.apiKeys = new ApiKeysResource(this.http);\n this.organizations = new OrganizationsResource(this.http);\n this.billing = new BillingResource(this.http);\n this.dashboard = new DashboardResource(this.http);\n this.health = new HealthResource(this.http);\n this.metrics = new MetricsResource(this.http);\n this.admin = new AdminResource(this.http, this.config.adminKey);\n this.ingest = new WebhookIngestionResource(this.http);\n\n this.config.debug?.(\"SpooledClient initialized\", {\n baseUrl: this.config.baseUrl,\n hasApiKey: !!this.config.apiKey,\n hasAccessToken: !!this.config.accessToken,\n });\n }\n\n /**\n * Real gRPC client for high-performance operations (HTTP/2 + Protobuf)\n *\n * The gRPC client is created lazily on first access to avoid\n * loading the proto file unless it's actually needed.\n *\n * @example\n * ```typescript\n * // Enqueue via gRPC\n * const { jobId } = await client.grpc.queue.enqueue({\n * queueName: 'my-queue',\n * payload: { message: 'Hello!' },\n * });\n *\n * // Stream jobs\n * for await (const job of client.grpc.queue.streamJobs({\n * queueName: 'my-queue',\n * workerId: 'worker-1',\n * })) {\n * console.log('Job:', job);\n * }\n * ```\n */\n get grpc(): SpooledGrpcClient {\n if (!this._grpc) {\n const grpcAddress = this.resolveGrpcAddress();\n const apiKey = this.config.apiKey;\n\n if (!apiKey) {\n throw new AuthenticationError(\"gRPC client requires an API key\");\n }\n\n this._grpc = new SpooledGrpcClient({\n address: grpcAddress,\n apiKey,\n timeout: this.config.timeout,\n });\n }\n return this._grpc;\n }\n\n /**\n * Create a realtime connection for WebSocket or SSE events\n *\n * @example\n * ```typescript\n * const realtime = await client.realtime();\n *\n * realtime.on('job.created', (event) => {\n * console.log('New job:', event.jobId);\n * });\n *\n * await realtime.connect();\n * await realtime.subscribe({ queueName: 'my-queue' });\n * ```\n */\n async realtime(options?: SpooledRealtimeOptions): Promise<SpooledRealtime> {\n // Get an initial JWT (fails fast on auth errors at call time).\n const token = await this.getJwtToken();\n\n return new SpooledRealtime({\n baseUrl: this.config.baseUrl,\n wsUrl: this.config.wsUrl,\n token,\n // Provider the realtime layer calls on every (re)connect. It returns a\n // cached JWT and only re-logs-in when the token is absent, near expiry,\n // or the transport asks to force a refresh (e.g. after a 401 upgrade).\n tokenProvider: (forceRefresh) => this.getJwtToken(forceRefresh),\n ...options,\n // Only forward debug when the client actually has a logger, so we never\n // hand the realtime layer an explicit `debug: undefined`. The WS/SSE\n // constructors also guard against this, but keeping the undefined out of\n // the option object makes the intent clear at the call site.\n ...(this.config.debug ? { debug: this.config.debug } : {}),\n });\n }\n\n /**\n * Get or acquire a JWT token for realtime connections.\n *\n * The realtime layer calls this on every (re)connect. We cache the JWT and\n * reuse it until it nears expiry so a reconnect storm doesn't hammer\n * /auth/login and trip its rate limit. A fresh login happens only when the\n * cached token is absent, within ~60s of its `exp`, or a refresh is forced.\n *\n * @param forceRefresh Bypass the cache and mint a new token. Set by the\n * transport when the server rejected the current token (e.g. a 401 on the\n * WebSocket upgrade), so a stale/revoked token is replaced without waiting\n * for it to expire.\n */\n private async getJwtToken(forceRefresh = false): Promise<string> {\n // A JWT access token supplied directly: reuse it, refreshing via the\n // refresh token when it nears expiry (or when a refresh is forced).\n if (this.config.accessToken) {\n if (forceRefresh || this.shouldRefreshToken()) {\n return this.refreshAccessToken();\n }\n return this.config.accessToken;\n }\n\n // API-key auth: exchange the key for a JWT once, then reuse the cached JWT\n // across (re)connects until it nears expiry. Only then log in again.\n if (this.config.apiKey) {\n if (forceRefresh) {\n this.cachedJwt = null;\n }\n if (this.cachedJwt && !isJwtNearExpiry(this.cachedJwt)) {\n return this.cachedJwt;\n }\n return this.loginForJwt();\n }\n\n throw new AuthenticationError(\n \"No authentication method available for realtime connection\",\n );\n }\n\n /**\n * Exchange the API key for a JWT via /auth/login and cache the result.\n *\n * The JWT belongs to the realtime transport only. It must NOT replace the\n * REST bearer: an API-key client has no refresh token wired into its HTTP\n * layer, so after the JWT's 24 h lifetime every REST call (claim, complete,\n * heartbeat, create) would have failed with 401 for good. REST keeps using\n * the API key; realtime re-mints its own JWT near expiry (see\n * `getJwtToken`).\n *\n * Concurrent callers share a single in-flight login so a burst of reconnects\n * (e.g. WebSocket and SSE at once) issues just one request.\n */\n private async loginForJwt(): Promise<string> {\n if (this.jwtLoginPromise) {\n return this.jwtLoginPromise;\n }\n\n this.jwtLoginPromise = (async () => {\n const response = await this.auth.login({ apiKey: this.config.apiKey! });\n\n // Cache the token for future (re)connects; leave `http` auth alone.\n this.cachedJwt = response.accessToken;\n\n return response.accessToken;\n })();\n\n try {\n return await this.jwtLoginPromise;\n } finally {\n this.jwtLoginPromise = null;\n }\n }\n\n /**\n * Check if token should be refreshed\n */\n private shouldRefreshToken(): boolean {\n if (!this.tokenExpiresAt) {\n return false;\n }\n // Refresh 5 minutes before expiry\n const bufferMs = 5 * 60 * 1000;\n return Date.now() >= this.tokenExpiresAt - bufferMs;\n }\n\n /**\n * Refresh the access token\n */\n private async refreshAccessToken(): Promise<string> {\n // Deduplicate concurrent refresh requests\n if (this.refreshPromise) {\n return this.refreshPromise;\n }\n\n if (!this.config.refreshToken) {\n throw new AuthenticationError(\"No refresh token available\");\n }\n\n this.refreshPromise = this.doRefreshToken();\n\n try {\n return await this.refreshPromise;\n } finally {\n this.refreshPromise = null;\n }\n }\n\n /**\n * Actually perform the token refresh\n */\n private async doRefreshToken(): Promise<string> {\n const response = await this.auth.refresh({\n refreshToken: this.config.refreshToken!,\n });\n\n // Update state\n this.http.setAuthToken(response.accessToken);\n this.tokenExpiresAt = Date.now() + response.expiresIn * 1000;\n (this.config as ResolvedConfig).accessToken = response.accessToken;\n\n this.config.debug?.(\"Token refreshed successfully\");\n\n return response.accessToken;\n }\n\n /**\n * Get current configuration (read-only)\n */\n getConfig(): Readonly<ResolvedConfig> {\n return this.config;\n }\n\n /**\n * Rate-limit state from the most recent response that carried\n * `X-RateLimit-*` headers (API 0.1.122+): `limit`, `remaining`, `reset`\n * (from the Unix-seconds header), `scope` and, after a 429, `retryAfter`.\n * `undefined` until such a response arrives, and for servers or routes that\n * do not send the headers. A 429 also carries the same values on\n * `RateLimitError.rateLimitInfo`.\n */\n getRateLimitInfo(): RateLimitInfo | undefined {\n return this.http.getLastRateLimitInfo();\n }\n\n /**\n * Get circuit breaker statistics\n */\n getCircuitBreakerStats() {\n return this.circuitBreaker.getStats();\n }\n\n /**\n * Reset the circuit breaker\n */\n resetCircuitBreaker(): void {\n this.circuitBreaker.reset();\n }\n\n /**\n * Create a new client with different options\n */\n withOptions(options: Partial<SpooledClientConfig>): SpooledClient {\n return new SpooledClient({\n apiKey: this.config.apiKey,\n accessToken: this.config.accessToken,\n refreshToken: this.config.refreshToken,\n adminKey: this.config.adminKey,\n grpcAddress: this.config.grpcAddress,\n baseUrl: this.config.baseUrl,\n timeout: this.config.timeout,\n retry: this.config.retry,\n circuitBreaker: this.config.circuitBreaker,\n headers: this.config.headers,\n fetch: this.config.fetch,\n userAgent: this.config.userAgent,\n debug: this.config.debug ?? undefined,\n autoRefreshToken: this.config.autoRefreshToken,\n ...options,\n });\n }\n\n /**\n * Resolve gRPC address (host:port format)\n */\n private resolveGrpcAddress(): string {\n return this.config.grpcAddress;\n }\n\n /**\n * Close all connections including gRPC\n */\n close(): void {\n if (this._grpc) {\n this._grpc.close();\n this._grpc = null;\n }\n }\n}\n\n/**\n * Create a new SpooledClient instance\n *\n * @example\n * ```typescript\n * const client = createClient({\n * apiKey: process.env.SPOOLED_API_KEY\n * });\n * ```\n */\nexport function createClient(options: SpooledClientConfig): SpooledClient {\n return new SpooledClient(options);\n}\n\n/**\n * Decode a JWT's `exp` claim (seconds since epoch) without verifying the\n * signature — we only need the expiry to decide when to refresh, not to trust\n * the token. Returns null for a malformed token or one with no numeric `exp`.\n */\nexport function decodeJwtExp(token: string): number | null {\n const parts = token.split(\".\");\n if (parts.length < 2) {\n return null;\n }\n try {\n const payload = JSON.parse(base64UrlDecode(parts[1])) as { exp?: unknown };\n return typeof payload.exp === \"number\" ? payload.exp : null;\n } catch {\n return null;\n }\n}\n\n/**\n * True when a token is missing an `exp` we can read or is within `skewMs` of it.\n * A token whose expiry can't be decoded is treated as expiring, so we fall back\n * to a fresh login rather than reuse a token we can't reason about.\n */\nexport function isJwtNearExpiry(token: string, skewMs = 60_000): boolean {\n const exp = decodeJwtExp(token);\n if (exp === null) {\n return true;\n }\n return Date.now() >= exp * 1000 - skewMs;\n}\n\n/** Base64url-decode a JWT segment to a UTF-8 string, across Node and browsers. */\nfunction base64UrlDecode(segment: string): string {\n const b64 = segment.replace(/-/g, \"+\").replace(/_/g, \"/\");\n // Prefer Node's Buffer; fall back to atob for browsers / non-Node runtimes.\n // Referenced via globalThis so neither global is a hard dependency.\n if (typeof globalThis.Buffer !== \"undefined\") {\n return globalThis.Buffer.from(b64, \"base64\").toString(\"utf8\");\n }\n const binary = globalThis.atob(b64);\n const bytes = Uint8Array.from(binary, (c) => c.charCodeAt(0));\n return new globalThis.TextDecoder().decode(bytes);\n}\n","/**\n * Common Types\n *\n * Shared types used across the SDK.\n */\n\n/** JSON primitive types */\nexport type JsonPrimitive = string | number | boolean | null;\n\n/** JSON value type */\nexport type JsonValue = JsonPrimitive | JsonObject | JsonArray;\n\n/** JSON object type */\nexport interface JsonObject {\n [key: string]: JsonValue;\n}\n\n/** JSON array type */\nexport type JsonArray = JsonValue[];\n\n/** Job status enum values */\nexport type JobStatus =\n | \"pending\"\n | \"scheduled\"\n | \"processing\"\n | \"completed\"\n | \"failed\"\n | \"deadletter\"\n | \"cancelled\";\n\n/** Worker status enum values */\nexport type WorkerStatus = \"healthy\" | \"degraded\" | \"offline\" | \"draining\";\n\n/** Workflow status enum values */\nexport type WorkflowStatus =\n | \"pending\"\n | \"running\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\";\n\n/** Plan tier enum values */\nexport type PlanTier = \"free\" | \"starter\" | \"pro\" | \"enterprise\";\n\n/** Schedule run status */\nexport type ScheduleRunStatus = \"pending\" | \"running\" | \"completed\" | \"failed\";\n\n/** Webhook delivery status */\nexport type WebhookDeliveryStatus = \"pending\" | \"success\" | \"failed\";\n\n/**\n * Webhook event types.\n *\n * `job.deadlettered`, `job.retried`, `workflow.completed` and\n * `workflow.failed` need API 0.1.122 or later. The SDK does not check event\n * names in responses: a name newer than this list is passed through as a\n * string, so give a `switch` over it a `default` branch.\n */\nexport type WebhookEventType =\n | \"job.created\"\n | \"job.started\"\n | \"job.completed\"\n | \"job.failed\"\n | \"job.cancelled\"\n | \"queue.paused\"\n | \"queue.resumed\"\n | \"worker.registered\"\n | \"worker.deregistered\"\n | \"schedule.triggered\"\n /** Sent next to every `job.failed` whose `data.status` is `deadletter`. */\n | \"job.deadlettered\"\n /** A manual retry (job, DLQ or workflow retry) put the job back to pending. */\n | \"job.retried\"\n /** A workflow finished; announced at most once, up to ~10 s late. */\n | \"workflow.completed\"\n /** A workflow failed; announced at most once, up to ~10 s late. */\n | \"workflow.failed\";\n\n/**\n * Body format of an outgoing webhook (API 0.1.122+).\n *\n * `json` (the default) is the signed JSON envelope. `slack`, `discord` and\n * `teams` send one short chat message built from the event, so a chat\n * service's incoming-webhook URL can be used as it is (`teams` is the legacy\n * Office 365 connector `MessageCard`; Teams Workflows URLs reject it).\n */\nexport type WebhookFormat = \"json\" | \"slack\" | \"discord\" | \"teams\";\n\n/** Dependency mode for workflows */\nexport type DependencyMode = \"all\" | \"any\";\n\n/** Pagination parameters */\nexport interface PaginationParams {\n /** Maximum number of results */\n limit?: number;\n /** Offset for pagination */\n offset?: number;\n}\n\n/** List parameters with optional sorting */\nexport interface ListParams extends PaginationParams {\n /** Field to order by */\n orderBy?: string;\n /** Sort direction */\n orderDir?: \"asc\" | \"desc\";\n}\n\n/** Paginated response wrapper */\nexport interface PaginatedResponse<T> {\n /** Items in current page */\n data: T[];\n /** Total count (if available) */\n total?: number;\n /** Current page offset */\n offset: number;\n /** Page size limit */\n limit: number;\n /** Whether there are more results */\n hasMore: boolean;\n}\n\n/**\n * One page of a list endpoint that reports `X-Has-More` (API 0.1.122+):\n * `GET /jobs`, `GET /jobs/dlq` and `GET /jobs/{id}/history`.\n *\n * The response body stays a bare array; `hasMore` comes from the header.\n */\nexport interface ListPage<T> {\n /** Items of this page, in the server's order */\n data: T[];\n /**\n * `true` when another page follows: ask again with\n * `offset + data.length`. From the `X-Has-More` header; an older server\n * without it gets a guess from the page size (a full page means \"maybe\").\n */\n hasMore: boolean;\n}\n\n/**\n * Helper to create a paginated response from an array\n */\nexport function createPaginatedResponse<T>(\n items: T[],\n limit: number,\n offset: number = 0,\n total?: number,\n): PaginatedResponse<T> {\n return {\n data: items,\n total,\n offset,\n limit,\n hasMore: items.length === limit,\n };\n}\n","/**\n * gRPC Types\n *\n * Types that mirror the protobuf definitions in spooled.proto.\n * Uses proper enum names matching the proto (JOB_STATUS_PENDING, etc.)\n */\n\nimport type * as grpc from \"@grpc/grpc-js\";\n\n// ============================================================================\n// Job Status Enum\n// ============================================================================\n\n/** Job status enum values (proto-style naming) */\nexport enum GrpcJobStatus {\n JOB_STATUS_UNSPECIFIED = \"JOB_STATUS_UNSPECIFIED\",\n JOB_STATUS_PENDING = \"JOB_STATUS_PENDING\",\n JOB_STATUS_SCHEDULED = \"JOB_STATUS_SCHEDULED\",\n JOB_STATUS_PROCESSING = \"JOB_STATUS_PROCESSING\",\n JOB_STATUS_COMPLETED = \"JOB_STATUS_COMPLETED\",\n JOB_STATUS_FAILED = \"JOB_STATUS_FAILED\",\n JOB_STATUS_DEADLETTER = \"JOB_STATUS_DEADLETTER\",\n JOB_STATUS_CANCELLED = \"JOB_STATUS_CANCELLED\",\n}\n\n/** Numeric job status values (for backward compatibility) */\nexport const GrpcJobStatusNumber = {\n UNSPECIFIED: 0,\n PENDING: 1,\n SCHEDULED: 2,\n PROCESSING: 3,\n COMPLETED: 4,\n FAILED: 5,\n DEADLETTER: 6,\n CANCELLED: 7,\n} as const;\n\n// ============================================================================\n// Timestamp handling\n// ============================================================================\n\n/** Timestamp as returned by gRPC (can be object or ISO string) */\nexport interface GrpcTimestamp {\n seconds?: string | number;\n nanos?: number;\n}\n\n/** Convert timestamp to Date */\nexport function timestampToDate(\n ts: GrpcTimestamp | string | undefined | null,\n): Date | null {\n if (!ts) return null;\n\n if (typeof ts === \"string\") {\n return new Date(ts);\n }\n\n const seconds =\n typeof ts.seconds === \"string\"\n ? parseInt(ts.seconds, 10)\n : (ts.seconds ?? 0);\n const nanos = ts.nanos ?? 0;\n return new Date(seconds * 1000 + Math.floor(nanos / 1_000_000));\n}\n\n/** Convert Date to timestamp object */\nexport function dateToTimestamp(date: Date | string): GrpcTimestamp {\n const d = typeof date === \"string\" ? new Date(date) : date;\n const ms = d.getTime();\n return {\n seconds: Math.floor(ms / 1000).toString(),\n nanos: (ms % 1000) * 1_000_000,\n };\n}\n\n// ============================================================================\n// Job Message\n// ============================================================================\n\n/** Job message as returned by gRPC */\nexport interface GrpcJob {\n id: string;\n organizationId: string;\n queueName: string;\n status: GrpcJobStatus | string;\n /** Payload as google.protobuf.Struct (object) */\n payload?: Record<string, unknown> | null;\n /** Result as google.protobuf.Struct (object) */\n result?: Record<string, unknown> | null;\n retryCount: number;\n maxRetries: number;\n lastError?: string | null;\n priority: number;\n timeoutSeconds: number;\n createdAt?: GrpcTimestamp | string | null;\n scheduledAt?: GrpcTimestamp | string | null;\n startedAt?: GrpcTimestamp | string | null;\n completedAt?: GrpcTimestamp | string | null;\n leaseExpiresAt?: GrpcTimestamp | string | null;\n assignedWorkerId?: string | null;\n idempotencyKey?: string | null;\n /**\n * Lease fencing token (proto `lease_id`). Returned on dequeue; echo it back\n * in Complete/Fail/RenewLease so the operation applies only to the lease\n * this worker actually holds (empty = legacy worker_id fence).\n */\n leaseId?: string | null;\n}\n\n// ============================================================================\n// Queue Service - Request/Response Types\n// ============================================================================\n\n/** Enqueue request */\nexport interface GrpcEnqueueRequest {\n queueName: string;\n /** Payload as object (will be converted to google.protobuf.Struct) */\n payload?: Record<string, unknown>;\n priority?: number;\n maxRetries?: number;\n timeoutSeconds?: number;\n scheduledAt?: GrpcTimestamp | string;\n idempotencyKey?: string;\n tags?: Record<string, string>;\n}\n\n/** Enqueue response */\nexport interface GrpcEnqueueResponse {\n jobId: string;\n created: boolean;\n}\n\n/** Dequeue request */\nexport interface GrpcDequeueRequest {\n queueName: string;\n workerId: string;\n leaseDurationSecs?: number;\n batchSize?: number;\n}\n\n/** Dequeue response */\nexport interface GrpcDequeueResponse {\n jobs: GrpcJob[];\n}\n\n/** Complete request */\nexport interface GrpcCompleteRequest {\n jobId: string;\n workerId: string;\n /** Result as object (will be converted to google.protobuf.Struct) */\n result?: Record<string, unknown>;\n /**\n * Lease fencing token from the dequeued job (proto `lease_id`). Required: the\n * server rejects a settlement without it with INVALID_ARGUMENT.\n */\n leaseId: string;\n}\n\n/** Complete response */\nexport interface GrpcCompleteResponse {\n success: boolean;\n}\n\n/** Fail request */\nexport interface GrpcFailRequest {\n jobId: string;\n workerId: string;\n error: string;\n /**\n * Retry the job (until its `maxRetries` run out) instead of dead-lettering it\n * at once. Defaults to `true`, which the SDK sends explicitly, so servers\n * from before proto field 4 became `optional bool` (where an absent field\n * read as `false` and dead-lettered the job on its first failure) behave the\n * same. Pass `false` to dead-letter the job now, whatever `maxRetries` says:\n * the SDK puts `retry = false` on the wire with field presence.\n */\n retry?: boolean;\n /**\n * Lease fencing token from the dequeued job (proto `lease_id`). Required: the\n * server rejects a settlement without it with INVALID_ARGUMENT.\n */\n leaseId: string;\n}\n\n/** Fail response */\nexport interface GrpcFailResponse {\n success: boolean;\n willRetry?: boolean;\n nextRetryDelaySecs?: number;\n}\n\n/** Renew lease request */\nexport interface GrpcRenewLeaseRequest {\n jobId: string;\n workerId: string;\n extensionSecs: number;\n /**\n * Lease fencing token from the dequeued job (proto `lease_id`). Required: the\n * server rejects a renewal without it with INVALID_ARGUMENT.\n */\n leaseId: string;\n}\n\n/** Renew lease response */\nexport interface GrpcRenewLeaseResponse {\n success: boolean;\n newExpiresAt?: GrpcTimestamp | string | null;\n}\n\n/** Get job request */\nexport interface GrpcGetJobRequest {\n jobId: string;\n}\n\n/** Get job response */\nexport interface GrpcGetJobResponse {\n job?: GrpcJob | null;\n}\n\n/** Get queue stats request */\nexport interface GrpcGetQueueStatsRequest {\n queueName: string;\n}\n\n/** Get queue stats response */\nexport interface GrpcGetQueueStatsResponse {\n queueName: string;\n pending: number | string;\n scheduled: number | string;\n processing: number | string;\n completed: number | string;\n failed: number | string;\n deadletter: number | string;\n total: number | string;\n maxAgeMs?: number | string | null;\n}\n\n/** Stream jobs request (server streaming) */\nexport interface GrpcStreamJobsRequest {\n queueName: string;\n workerId: string;\n leaseDurationSecs?: number;\n}\n\n// ============================================================================\n// Bidirectional Streaming Types\n// ============================================================================\n\n/** Process request (for bidirectional streaming) */\nexport interface GrpcProcessRequest {\n dequeue?: GrpcDequeueRequest;\n complete?: GrpcCompleteRequest;\n fail?: GrpcFailRequest;\n renewLease?: GrpcRenewLeaseRequest;\n}\n\n/** Error response */\nexport interface GrpcErrorResponse {\n code: string;\n message: string;\n}\n\n/** Process response (for bidirectional streaming) */\nexport interface GrpcProcessResponse {\n job?: GrpcJob;\n complete?: GrpcCompleteResponse;\n fail?: GrpcFailResponse;\n renewLease?: GrpcRenewLeaseResponse;\n error?: GrpcErrorResponse;\n}\n\n// ============================================================================\n// Worker Service Types\n// ============================================================================\n\n/** Register worker request */\nexport interface GrpcRegisterWorkerRequest {\n queueName: string;\n hostname?: string;\n workerType?: string;\n maxConcurrency?: number;\n version?: string;\n metadata?: Record<string, string>;\n /**\n * Stable worker id (proto `optional string worker_id = 7`): 1-128\n * characters, letters, digits, `-`, `_` and `.`.\n *\n * Send the same id after a restart and the server updates that worker\n * instead of adding one, so a restarting worker does not count twice against\n * the plan's worker limit. Omitted or empty: the server assigns a new id. An\n * id that another organization already uses fails with ALREADY_EXISTS\n * (`ConflictError`). Servers older than API 0.1.119 ignore the field.\n */\n workerId?: string;\n}\n\n/** Register worker response */\nexport interface GrpcRegisterWorkerResponse {\n workerId: string;\n leaseDurationSecs: number;\n heartbeatIntervalSecs: number;\n}\n\n/** Heartbeat request */\nexport interface GrpcHeartbeatRequest {\n workerId: string;\n currentJobs?: number;\n status?: string;\n metadata?: Record<string, string>;\n}\n\n/** Heartbeat response */\nexport interface GrpcHeartbeatResponse {\n acknowledged: boolean;\n shouldDrain?: boolean;\n}\n\n/** Deregister request */\nexport interface GrpcDeregisterRequest {\n workerId: string;\n}\n\n/** Deregister response */\nexport interface GrpcDeregisterResponse {\n success: boolean;\n}\n\n// ============================================================================\n// gRPC Client Options\n// ============================================================================\n\n/** Options for creating a gRPC client */\nexport interface GrpcClientOptions {\n /** gRPC server address (host:port) */\n address: string;\n /** API key for authentication */\n apiKey: string;\n /** Use TLS (default: true for production, false for localhost) */\n useTls?: boolean;\n /** Custom channel credentials */\n credentials?: grpc.ChannelCredentials;\n /** Channel options */\n channelOptions?: grpc.ChannelOptions;\n /** Deadline for unary gRPC calls in milliseconds. Streams are not bounded unless explicitly configured. */\n timeout?: number;\n}\n\n// ============================================================================\n// Legacy types (backward compatibility)\n// ============================================================================\n\n/** @deprecated Use GrpcEnqueueRequest */\nexport type GrpcEnqueueJobParams = GrpcEnqueueRequest & {\n organizationId?: string;\n};\n\n/** @deprecated Use GrpcEnqueueResponse */\nexport type GrpcEnqueueJobResponse = GrpcEnqueueResponse;\n\n/** @deprecated Use GrpcDequeueRequest */\nexport type GrpcDequeueJobParams = GrpcDequeueRequest & {\n organizationId?: string;\n leaseDurationSeconds?: number;\n};\n\n/** @deprecated Use GrpcDequeueResponse */\nexport interface GrpcDequeueJobResponse {\n job?: GrpcJob | null;\n}\n\n/** @deprecated Use GrpcCompleteRequest */\nexport type GrpcCompleteJobParams = GrpcCompleteRequest;\n\n/** @deprecated Use GrpcCompleteResponse */\nexport type GrpcCompleteJobResponse = GrpcCompleteResponse;\n\n/** @deprecated Use GrpcFailRequest */\nexport interface GrpcFailJobParams {\n jobId: string;\n workerId: string;\n errorMessage: string;\n}\n\n/** @deprecated Use GrpcFailResponse */\nexport type GrpcFailJobResponse = GrpcFailResponse;\n\n/** @deprecated Use GrpcRenewLeaseRequest */\nexport interface GrpcRenewLeaseParams {\n jobId: string;\n workerId: string;\n leaseDurationSeconds: number;\n}\n\n/** @deprecated Use GrpcRenewLeaseResponse */\nexport interface GrpcRenewLeaseResponse_Legacy {\n renewed: boolean;\n newLeaseExpiresAt?: string | null;\n}\n\n/** @deprecated Use GrpcGetQueueStatsResponse */\nexport interface GrpcGetQueueStatsResponse_Legacy {\n queueName: string;\n pending: number;\n scheduled: number;\n processing: number;\n completed: number;\n failed: number;\n deadletter: number;\n total: number;\n maxAgeMs?: number | null;\n}\n\n/** @deprecated Use GrpcRegisterWorkerRequest */\nexport interface GrpcRegisterWorkerParams {\n workerId: string;\n organizationId?: string;\n queueNames: string[];\n maxConcurrentJobs?: number;\n hostname?: string;\n metadata?: Record<string, unknown> | string;\n}\n\n/** @deprecated Use GrpcRegisterWorkerResponse */\nexport interface GrpcRegisterWorkerResponse_Legacy {\n registered: boolean;\n heartbeatIntervalSeconds: number;\n}\n\n/** @deprecated Use GrpcHeartbeatRequest */\nexport interface GrpcHeartbeatParams {\n workerId: string;\n currentJobIds: string[];\n status: string;\n}\n\n/** @deprecated Use GrpcHeartbeatResponse */\nexport type GrpcHeartbeatResponse_Legacy = GrpcHeartbeatResponse;\n","/**\n * Spooled Worker\n *\n * Worker runtime for processing jobs from a queue.\n */\n\nimport type { SpooledClient } from \"../client.js\";\nimport { SDK_VERSION } from \"../config.js\";\nimport type { JsonValue } from \"../types/common.js\";\nimport type { ClaimedJob } from \"../types/jobs.js\";\nimport { coerceFailureMessage } from \"../utils/failure.js\";\nimport type {\n SpooledWorkerOptions,\n WorkerState,\n JobHandler,\n JobContext,\n WorkerEvent,\n WorkerEventData,\n ActiveJob,\n} from \"./types.js\";\nimport { hostname as osHostname } from \"os\";\n\n/** Default options */\nconst DEFAULT_OPTIONS = {\n concurrency: 5,\n pollInterval: 1000,\n leaseDuration: 30,\n heartbeatFraction: 0.5,\n autoStart: false,\n shutdownTimeout: 30000,\n} as const;\n\n/** Event handler type */\ntype EventHandler<E extends WorkerEvent> = (data: WorkerEventData[E]) => void;\n\n/** Failure text sent when a handler outlives the job's `timeoutSeconds`. */\nconst JOB_TIMEOUT_MESSAGE = \"Job timeout exceeded\";\n\n/** Failure text sent for a handler still running when the shutdown grace ends. */\nconst SHUTDOWN_TIMEOUT_MESSAGE = \"Worker shutdown timeout\";\n\n/** Longest delay `setTimeout` accepts (a larger one fires immediately). */\nconst MAX_TIMER_MS = 2 ** 31 - 1;\n\n/** How a handler run ended. Decided once per execution. */\ntype HandlerOutcome =\n | { kind: \"returned\"; value: JsonValue | void }\n | { kind: \"threw\"; error: unknown }\n | { kind: \"timeout\" };\n\n/**\n * Spooled Worker\n *\n * @example\n * ```typescript\n * const worker = new SpooledWorker(client, {\n * queueName: 'my-queue',\n * concurrency: 10,\n * });\n *\n * worker.process(async (ctx) => {\n * console.log('Processing job:', ctx.jobId);\n * await doSomeWork(ctx.payload);\n * return { success: true };\n * });\n *\n * await worker.start();\n *\n * // Graceful shutdown\n * process.on('SIGTERM', () => worker.stop());\n * ```\n */\nexport class SpooledWorker {\n private readonly client: SpooledClient;\n /**\n * Options with every defaultable field filled in. `workerId` stays optional:\n * there is no sensible default for it, and omitting it is what makes the\n * server mint a UUID.\n */\n private readonly options: Required<Omit<SpooledWorkerOptions, \"workerId\">> &\n Pick<SpooledWorkerOptions, \"workerId\">;\n private readonly debug: (msg: string, meta?: unknown) => void;\n\n private state: WorkerState = \"idle\";\n private workerId: string | null = null;\n private handler: JobHandler | null = null;\n private activeJobs: Map<symbol, ActiveJob> = new Map();\n private pollTimer: ReturnType<typeof setTimeout> | null = null;\n private workerHeartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private shutdownPromise: Promise<void> | null = null;\n /** The claim request currently on the wire, so a stop can wait for its jobs. */\n private pollInFlight: Promise<void> | null = null;\n /** Wakes the shutdown drain when the last active job has been acked. */\n private drainWaiter: (() => void) | null = null;\n\n // Event handlers\n private eventHandlers: Map<WorkerEvent, Set<EventHandler<WorkerEvent>>> =\n new Map();\n\n constructor(client: SpooledClient, options: SpooledWorkerOptions) {\n this.client = client;\n this.options = {\n ...DEFAULT_OPTIONS,\n hostname: osHostname(),\n workerType: \"nodejs\",\n version: SDK_VERSION,\n metadata: {},\n ...options,\n } as Required<Omit<SpooledWorkerOptions, \"workerId\">> &\n Pick<SpooledWorkerOptions, \"workerId\">;\n\n // Get debug from client config\n const config = client.getConfig();\n this.debug = config.debug ?? (() => {});\n\n if (this.options.autoStart) {\n // Defer to next tick to allow process() to be called. start() already\n // reports a failed registration through the \"error\" event; the catch only\n // keeps it from becoming an unhandled rejection that crashes the process.\n setImmediate(() => {\n this.start().catch((error) => {\n this.debug(\"Auto-start failed\", error);\n });\n });\n }\n }\n\n /**\n * Get current worker state\n */\n getState(): WorkerState {\n return this.state;\n }\n\n /**\n * Get worker ID (available after start)\n */\n getWorkerId(): string | null {\n return this.workerId;\n }\n\n /**\n * Get number of active jobs\n */\n getActiveJobCount(): number {\n return this.activeJobs.size;\n }\n\n /**\n * Register job handler\n */\n process(handler: JobHandler): void {\n if (this.state !== \"idle\") {\n throw new Error(\"Cannot set handler after worker has started\");\n }\n this.handler = handler;\n }\n\n /**\n * Start the worker\n */\n async start(): Promise<void> {\n if (this.state !== \"idle\") {\n throw new Error(`Cannot start worker in state: ${this.state}`);\n }\n\n if (!this.handler) {\n throw new Error(\"No job handler registered. Call process() first.\");\n }\n\n this.state = \"starting\";\n this.debug(`Starting worker for queue: ${this.options.queueName}`);\n\n try {\n // Register with the API\n const registration = await this.client.workers.register({\n queueName: this.options.queueName,\n workerId: this.options.workerId,\n hostname: this.options.hostname,\n workerType: this.options.workerType,\n maxConcurrency: this.options.concurrency,\n metadata: this.options.metadata,\n version: this.options.version,\n });\n\n this.workerId = registration.id;\n this.debug(`Worker registered: ${this.workerId}`, registration);\n\n // Start worker heartbeat\n const heartbeatInterval = registration.heartbeatIntervalSecs * 1000;\n this.workerHeartbeatTimer = setInterval(() => {\n this.sendWorkerHeartbeat();\n }, heartbeatInterval);\n\n // Start polling\n this.state = \"running\";\n this.emit(\"started\", {\n workerId: this.workerId,\n queueName: this.options.queueName,\n });\n this.schedulePoll();\n } catch (error) {\n this.state = \"error\";\n this.emit(\"error\", { error: error as Error });\n throw error;\n }\n }\n\n /**\n * Stop the worker gracefully.\n *\n * Drains: the worker stops claiming, then lets running handlers finish for\n * up to `shutdownTimeout`. A handler that returns completes its job and one\n * that throws fails it, even though a stop was requested meanwhile; its\n * `signal` is NOT aborted during the grace period. Only handlers still\n * running when the timeout ends are aborted and failed with \"Worker shutdown\n * timeout\". The worker deregisters last, because deregistering returns every\n * job the worker still holds to the queue.\n */\n async stop(): Promise<void> {\n if (this.state !== \"running\") {\n return;\n }\n\n // Deduplicate concurrent stop calls\n if (this.shutdownPromise) {\n return this.shutdownPromise;\n }\n\n this.shutdownPromise = this.doStop();\n return this.shutdownPromise;\n }\n\n private async doStop(): Promise<void> {\n const deadline = Date.now() + this.options.shutdownTimeout;\n this.state = \"stopping\";\n this.debug(\"Stopping worker...\");\n\n // Stop polling\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n\n // A claim already on the wire still returns jobs this worker now holds\n // leases for. Let it land first so they join the drain below instead of\n // starting after the worker has deregistered.\n if (this.pollInFlight) {\n await this.pollInFlight;\n }\n\n // Drain: the worker heartbeat and every job heartbeat keep running while\n // handlers finish, so neither the worker nor a lease expires mid-drain.\n if (this.activeJobs.size > 0) {\n this.debug(\n `Waiting for ${this.activeJobs.size} active jobs to complete...`,\n );\n\n await this.waitForDrain(Math.max(0, deadline - Date.now()));\n\n // Whatever is still running outlived the grace period: abort and fail it.\n // A job whose handler returned just before the deadline is already\n // settled (its ack is in flight) and is awaited below, not failed.\n const stragglers = Array.from(this.activeJobs.values()).filter(\n (active) => !active.settled,\n );\n await Promise.all(stragglers.map((active) => this.abandonJob(active)));\n\n // Acks already on the wire must land before the worker deregisters,\n // otherwise deregistering re-queues a job that was just finished.\n await Promise.all(\n Array.from(this.activeJobs.values()).map((active) => active.ack),\n );\n }\n\n // Stop worker heartbeat\n if (this.workerHeartbeatTimer) {\n clearInterval(this.workerHeartbeatTimer);\n this.workerHeartbeatTimer = null;\n }\n\n // Deregister worker\n const workerId = this.workerId;\n if (workerId) {\n try {\n await this.client.workers.deregister(workerId);\n this.debug(\"Worker deregistered\");\n } catch (error) {\n this.debug(\"Failed to deregister worker\", error);\n }\n }\n\n this.state = \"stopped\";\n this.workerId = null;\n this.emit(\"stopped\", { workerId: workerId ?? \"\", reason: \"graceful\" });\n this.shutdownPromise = null;\n }\n\n /**\n * Add event listener\n */\n on<E extends WorkerEvent>(event: E, handler: EventHandler<E>): () => void {\n if (!this.eventHandlers.has(event)) {\n this.eventHandlers.set(event, new Set());\n }\n this.eventHandlers.get(event)!.add(handler as EventHandler<WorkerEvent>);\n return () => this.off(event, handler);\n }\n\n /**\n * Remove event listener\n */\n off<E extends WorkerEvent>(event: E, handler: EventHandler<E>): void {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.delete(handler as EventHandler<WorkerEvent>);\n }\n }\n\n // Private methods\n\n private emit<E extends WorkerEvent>(\n event: E,\n data: WorkerEventData[E],\n ): void {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n this.debug(\"Event handler error\", { event, error });\n }\n });\n }\n }\n\n private schedulePoll(): void {\n if (this.state !== \"running\") {\n return;\n }\n\n this.pollTimer = setTimeout(() => {\n this.pollTimer = null;\n const run = this.poll();\n this.pollInFlight = run;\n const done = () => {\n if (this.pollInFlight === run) {\n this.pollInFlight = null;\n }\n };\n run.then(done, done);\n }, this.options.pollInterval);\n }\n\n private async poll(): Promise<void> {\n if (this.state !== \"running\" || !this.workerId) {\n return;\n }\n\n // Check if we have capacity\n const availableSlots = this.options.concurrency - this.activeJobs.size;\n if (availableSlots <= 0) {\n this.schedulePoll();\n return;\n }\n\n try {\n // Claim jobs\n const result = await this.client.jobs.claim({\n queueName: this.options.queueName,\n workerId: this.workerId,\n limit: availableSlots,\n leaseDurationSecs: this.options.leaseDuration,\n });\n\n // Process claimed jobs\n for (const job of result.jobs) {\n this.processJob(job);\n }\n } catch (error) {\n this.debug(\"Poll failed\", error);\n this.emit(\"error\", { error: error as Error });\n }\n\n // Schedule next poll\n this.schedulePoll();\n }\n\n private processJob(job: ClaimedJob): void {\n this.emit(\"job:claimed\", { jobId: job.id, queueName: job.queueName });\n\n const abortController = new AbortController();\n const activeJob: ActiveJob = {\n executionId: Symbol(job.id),\n job,\n startedAt: new Date(),\n abortController,\n settled: false,\n };\n\n this.activeJobs.set(activeJob.executionId, activeJob);\n\n // Capture the immutable execution so a replacement lease cannot be borrowed.\n const heartbeatInterval =\n this.options.leaseDuration * this.options.heartbeatFraction * 1000;\n activeJob.heartbeatTimer = setInterval(() => {\n this.sendJobHeartbeat(activeJob);\n }, heartbeatInterval);\n\n // Execute handler\n this.executeHandler(activeJob);\n }\n\n private async executeHandler(activeJob: ActiveJob): Promise<void> {\n const { job, abortController } = activeJob;\n const { signal } = abortController;\n\n this.emit(\"job:started\", { jobId: job.id, queueName: job.queueName });\n\n const context: JobContext = {\n jobId: job.id,\n queueName: job.queueName,\n payload: job.payload,\n retryCount: job.retryCount,\n maxRetries: job.maxRetries,\n signal,\n progress: async (percent: number, message?: string) => {\n const boundedPercent = Math.max(0, Math.min(100, percent));\n this.debug(`[${job.id}] progress ${boundedPercent}%`, message);\n },\n log: (level, message, meta) => {\n this.debug(`[${job.id}] [${level}] ${message}`, meta);\n },\n };\n\n try {\n const outcome = await this.runHandler(activeJob, context);\n\n // The shutdown drain already failed this job while its handler was still\n // running; the lease is gone, so a late result must not be sent.\n if (activeJob.settled) {\n this.debug(`Job ${job.id} was already settled; dropping late result`);\n return;\n }\n activeJob.settled = true;\n\n // The abort signal is only a hint to the handler. Whatever the handler\n // did decides the ack: a result that arrives after a stop was requested\n // is still sent, never silently dropped.\n switch (outcome.kind) {\n case \"returned\":\n activeJob.ack = this.completeJob(job, outcome.value ?? undefined);\n break;\n case \"threw\":\n activeJob.ack = this.failJob(\n job,\n outcome.error instanceof Error\n ? outcome.error.message\n : String(outcome.error),\n );\n break;\n case \"timeout\":\n // Stop the handler if it listens, then fail the job: extending the\n // lease of a hung handler forever would keep the job and its\n // concurrency slot stuck.\n abortController.abort(new Error(JOB_TIMEOUT_MESSAGE));\n this.emit(\"job:timeout\", {\n jobId: job.id,\n queueName: job.queueName,\n });\n activeJob.ack = this.failJob(job, JOB_TIMEOUT_MESSAGE);\n break;\n }\n await activeJob.ack;\n } finally {\n this.cleanupJob(activeJob);\n }\n }\n\n /**\n * Run the handler, racing it against the job's `timeoutSeconds`.\n * Never rejects: a throw (sync or async) is reported as an outcome.\n */\n private runHandler(\n activeJob: ActiveJob,\n context: JobContext,\n ): Promise<HandlerOutcome> {\n const run = (async (): Promise<HandlerOutcome> => {\n try {\n return { kind: \"returned\", value: await this.handler!(context) };\n } catch (error) {\n return { kind: \"threw\", error };\n }\n })();\n\n const { timeoutSeconds } = activeJob.job;\n if (typeof timeoutSeconds !== \"number\" || !(timeoutSeconds > 0)) {\n return run;\n }\n\n return new Promise<HandlerOutcome>((resolve) => {\n activeJob.timeoutTimer = setTimeout(\n () => resolve({ kind: \"timeout\" }),\n Math.min(timeoutSeconds * 1000, MAX_TIMER_MS),\n );\n run.then((outcome) => {\n this.clearTimeoutTimer(activeJob);\n resolve(outcome);\n });\n });\n }\n\n /** Abort a handler that outlived the shutdown grace period and fail its job. */\n private async abandonJob(activeJob: ActiveJob): Promise<void> {\n this.debug(`Force-failing job ${activeJob.job.id} due to shutdown timeout`);\n // Mark first: the handler may react to the abort, or finish later, and its\n // outcome must not be acked on top of this failure.\n activeJob.settled = true;\n activeJob.abortController.abort(new Error(SHUTDOWN_TIMEOUT_MESSAGE));\n activeJob.ack = this.failJob(activeJob.job, SHUTDOWN_TIMEOUT_MESSAGE);\n await activeJob.ack;\n // The handler's finally may never run if user code ignores the abort\n // signal, so explicitly clear this exact execution's timers.\n this.cleanupJob(activeJob);\n }\n\n private async completeJob(\n job: ClaimedJob,\n result?: JsonValue,\n ): Promise<void> {\n if (!this.workerId) return;\n\n try {\n await this.client.jobs.complete(job.id, {\n workerId: this.workerId,\n result,\n ...(job.leaseId != null && { leaseId: job.leaseId }),\n });\n\n this.emit(\"job:completed\", {\n jobId: job.id,\n queueName: job.queueName,\n result,\n });\n } catch (error) {\n // The ack was already retried by the HTTP layer; what is left is a job\n // that finished but could not be reported.\n this.debug(`Failed to complete job ${job.id}`, error);\n this.emit(\"error\", { error: error as Error });\n }\n }\n\n private async failJob(job: ClaimedJob, errorMessage: string): Promise<void> {\n if (!this.workerId) return;\n\n const willRetry = job.retryCount < job.maxRetries;\n // The API rejects empty or over-long failure text with a 400, which would\n // leave the job processing until its lease expired.\n const message = coerceFailureMessage(errorMessage);\n\n try {\n await this.client.jobs.fail(job.id, {\n workerId: this.workerId,\n error: message,\n ...(job.leaseId != null && { leaseId: job.leaseId }),\n });\n\n this.emit(\"job:failed\", {\n jobId: job.id,\n queueName: job.queueName,\n error: message,\n willRetry,\n });\n } catch (error) {\n this.debug(`Failed to fail job ${job.id}`, error);\n this.emit(\"error\", { error: error as Error });\n }\n }\n\n private clearTimeoutTimer(activeJob: ActiveJob): void {\n if (activeJob.timeoutTimer) {\n clearTimeout(activeJob.timeoutTimer);\n activeJob.timeoutTimer = undefined;\n }\n }\n\n private cleanupJob(activeJob: ActiveJob): void {\n if (activeJob.heartbeatTimer) {\n clearInterval(activeJob.heartbeatTimer);\n activeJob.heartbeatTimer = undefined;\n }\n this.clearTimeoutTimer(activeJob);\n\n if (this.activeJobs.get(activeJob.executionId) === activeJob) {\n this.activeJobs.delete(activeJob.executionId);\n if (this.activeJobs.size === 0) {\n this.drainWaiter?.();\n }\n }\n }\n\n private async sendJobHeartbeat(activeJob: ActiveJob): Promise<void> {\n if (!this.workerId) return;\n\n const { job } = activeJob;\n\n try {\n await this.client.jobs.heartbeat(job.id, {\n workerId: this.workerId,\n leaseDurationSecs: this.options.leaseDuration,\n ...(job.leaseId != null && { leaseId: job.leaseId }),\n });\n } catch (error) {\n this.debug(`Job heartbeat failed for ${job.id}`, error);\n }\n }\n\n private async sendWorkerHeartbeat(): Promise<void> {\n // Keep beating through the shutdown drain: a long `shutdownTimeout` would\n // otherwise let the stale-worker reaper take the worker (and its jobs).\n if (\n !this.workerId ||\n (this.state !== \"running\" && this.state !== \"stopping\")\n ) {\n return;\n }\n\n try {\n await this.client.workers.heartbeat(this.workerId, {\n currentJobs: this.activeJobs.size,\n status: \"healthy\",\n });\n } catch (error) {\n this.debug(\"Worker heartbeat failed\", error);\n }\n }\n\n /**\n * Resolve once no job is active, or after `timeoutMs`. The timer is always\n * cleared, so a clean stop leaves nothing that keeps the process alive.\n */\n private waitForDrain(timeoutMs: number): Promise<void> {\n if (this.activeJobs.size === 0) {\n return Promise.resolve();\n }\n return new Promise<void>((resolve) => {\n const timer = setTimeout(() => {\n this.drainWaiter = null;\n resolve();\n }, timeoutMs);\n this.drainWaiter = () => {\n clearTimeout(timer);\n this.drainWaiter = null;\n resolve();\n };\n });\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/config.ts","../src/errors.ts","../src/utils/casing.ts","../src/utils/retry.ts","../src/utils/json.ts","../src/utils/http.ts","../src/utils/circuit-breaker.ts","../src/resources/auth.ts","../src/utils/failure.ts","../src/utils/paging.ts","../src/resources/jobs.ts","../src/resources/queues.ts","../src/resources/workers.ts","../src/resources/schedules.ts","../src/resources/workflows.ts","../src/resources/webhooks.ts","../src/resources/api-keys.ts","../src/resources/organizations.ts","../src/resources/billing.ts","../src/resources/dashboard.ts","../src/resources/health.ts","../src/resources/metrics.ts","../src/resources/admin.ts","../src/resources/webhook-ingestion.ts","../src/realtime/event-map.ts","../src/realtime/websocket.ts","../src/realtime/sse.ts","../src/realtime/index.ts","../src/grpc/loader.ts","../src/grpc/encode.ts","../src/grpc/streaming.ts","../src/grpc/client.ts","../src/client.ts","../src/types/common.ts","../src/grpc/types.ts","../src/worker/worker.ts"],"names":["CircuitState","status","dirname","fileURLToPath","join","existsSync","protoLoader","grpc","grpc2","credentials","GrpcJobStatus","osHostname"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * SDK Configuration\n *\n * Defines configuration types and defaults for the Spooled SDK.\n */\n\nimport type { CircuitBreakerOptions } from \"./utils/circuit-breaker.js\";\n\n/** Retry configuration options */\nexport interface RetryConfig {\n /** Maximum number of retry attempts (default: 3) */\n maxRetries: number;\n /** Base delay in milliseconds for exponential backoff (default: 1000) */\n baseDelay: number;\n /** Maximum delay in milliseconds (default: 30000) */\n maxDelay: number;\n /** Exponential backoff factor (default: 2) */\n factor: number;\n /** Whether to add jitter to delays (default: true) */\n jitter: boolean;\n /** Custom function to determine if an error is retryable */\n retryOn?: (error: Error, attempt: number) => boolean;\n}\n\n/** Circuit breaker configuration options */\nexport interface CircuitBreakerConfig {\n /** Whether circuit breaker is enabled (default: true) */\n enabled: boolean;\n /** Number of failures before opening the circuit (default: 5) */\n failureThreshold: number;\n /** Number of successes in half-open state to close circuit (default: 3) */\n successThreshold: number;\n /** Time in milliseconds to wait before trying again after opening (default: 30000) */\n timeout: number;\n}\n\n/** Debug logging function type */\nexport type DebugFn = (message: string, meta?: unknown) => void;\n\n/** Main SDK configuration options */\nexport interface SpooledClientConfig {\n /** API key for authentication (starts with sp_live_, sp_test_, sk_live_, or sk_test_) */\n apiKey?: string;\n /** JWT access token (alternative to API key) */\n accessToken?: string;\n /** JWT refresh token for automatic token renewal */\n refreshToken?: string;\n /** Admin API key (for /api/v1/admin/* endpoints; uses X-Admin-Key header) */\n adminKey?: string;\n /** Base URL for the REST API (default: https://api.spooled.cloud) */\n baseUrl?: string;\n /** WebSocket URL for realtime events (default: derived from baseUrl, e.g., wss://api.spooled.cloud) */\n wsUrl?: string;\n /** gRPC server address (default: grpc.spooled.cloud:443) */\n grpcAddress?: string;\n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n /** Number of retry attempts (shorthand for retry.maxRetries) */\n retries?: number;\n /** Base retry delay in milliseconds (shorthand for retry.baseDelay) */\n retryDelay?: number;\n /** Full retry configuration */\n retry?: Partial<RetryConfig>;\n /**\n * Circuit breaker configuration. Besides the thresholds it takes\n * `isFailure` (which errors count as failures) and `onStateChange`.\n */\n circuitBreaker?: Partial<CircuitBreakerOptions>;\n /** Additional headers to include in all requests */\n headers?: Record<string, string>;\n /** Custom fetch implementation (for testing or special runtimes) */\n fetch?: typeof fetch;\n /** Custom user agent string */\n userAgent?: string;\n /** Enable debug logging */\n debug?: boolean | DebugFn;\n /** Whether to automatically refresh tokens when they expire (default: true) */\n autoRefreshToken?: boolean;\n}\n\n/** Resolved configuration with all defaults applied */\nexport interface ResolvedConfig {\n apiKey?: string;\n accessToken?: string;\n refreshToken?: string;\n adminKey?: string;\n baseUrl: string;\n wsUrl: string;\n grpcAddress: string;\n timeout: number;\n retry: RetryConfig;\n circuitBreaker: CircuitBreakerOptions;\n headers: Record<string, string>;\n fetch: typeof fetch;\n userAgent: string;\n debug: DebugFn | null;\n autoRefreshToken: boolean;\n}\n\n/** Default configuration values */\nexport const DEFAULT_CONFIG = {\n baseUrl: \"https://api.spooled.cloud\",\n wsUrl: \"wss://api.spooled.cloud\",\n grpcAddress: \"grpc.spooled.cloud:443\",\n timeout: 30000,\n retry: {\n maxRetries: 3,\n baseDelay: 1000,\n maxDelay: 30000,\n factor: 2,\n jitter: true,\n } satisfies RetryConfig,\n circuitBreaker: {\n enabled: true,\n failureThreshold: 5,\n successThreshold: 3,\n timeout: 30000,\n } satisfies CircuitBreakerConfig,\n userAgent: \"@spooled/sdk-nodejs/1.5.0\",\n autoRefreshToken: true,\n} as const;\n\n/** SDK version */\nexport const SDK_VERSION = \"1.5.0\";\n\n/** API version prefix */\nexport const API_VERSION = \"v1\";\n\n/** API base path */\nexport const API_BASE_PATH = `/api/${API_VERSION}`;\n\n/**\n * Trim surrounding whitespace from a credential string and treat an\n * all-whitespace input as unset. Mirrors the trim policy in the Go, PHP,\n * and Python SDKs so behavior is consistent across languages.\n */\nfunction normalizeCredential(value: string | undefined): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed === \"\" ? undefined : trimmed;\n}\n\n/**\n * Resolve configuration by merging user options with defaults\n */\nexport function resolveConfig(options: SpooledClientConfig): ResolvedConfig {\n // Create debug function\n let debugFn: DebugFn | null = null;\n if (options.debug === true) {\n debugFn = (message: string, meta?: unknown) => {\n // eslint-disable-next-line no-console\n console.log(`[spooled-sdk] ${message}`, meta !== undefined ? meta : \"\");\n };\n } else if (typeof options.debug === \"function\") {\n debugFn = options.debug;\n }\n\n // Merge retry config\n const retry: RetryConfig = {\n ...DEFAULT_CONFIG.retry,\n ...options.retry,\n // Allow shorthand overrides\n ...(options.retries !== undefined && { maxRetries: options.retries }),\n ...(options.retryDelay !== undefined && { baseDelay: options.retryDelay }),\n };\n\n // Merge circuit breaker config\n const circuitBreaker: CircuitBreakerOptions = {\n ...DEFAULT_CONFIG.circuitBreaker,\n ...options.circuitBreaker,\n };\n\n // Build headers\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...options.headers,\n };\n\n // Resolve base URL first\n const baseUrl = options.baseUrl ?? DEFAULT_CONFIG.baseUrl;\n\n // Derive WebSocket URL from base URL if not explicitly set\n // Replace http(s):// with ws(s)://\n const derivedWsUrl = baseUrl.replace(/^http/, \"ws\");\n const wsUrl = options.wsUrl ?? derivedWsUrl;\n\n // Trim whitespace (including a stray trailing '\\n') from every credential.\n // Node's `undici` fetch rejects `Authorization: Bearer <key>\\n` with an\n // opaque `TypeError: HeaderValue` and users routinely paste keys from\n // `.env` files that include a newline; normalizing here keeps behavior\n // consistent with the Go, PHP, and Python SDKs.\n return {\n apiKey: normalizeCredential(options.apiKey),\n accessToken: normalizeCredential(options.accessToken),\n refreshToken: normalizeCredential(options.refreshToken),\n adminKey: normalizeCredential(options.adminKey),\n baseUrl,\n wsUrl,\n grpcAddress: options.grpcAddress ?? DEFAULT_CONFIG.grpcAddress,\n timeout: options.timeout ?? DEFAULT_CONFIG.timeout,\n retry,\n circuitBreaker,\n headers,\n fetch: options.fetch ?? globalThis.fetch,\n userAgent: options.userAgent ?? DEFAULT_CONFIG.userAgent,\n debug: debugFn,\n autoRefreshToken:\n options.autoRefreshToken ?? DEFAULT_CONFIG.autoRefreshToken,\n };\n}\n\n/**\n * Validate configuration options\n * @throws Error if configuration is invalid\n */\nexport function validateConfig(config: ResolvedConfig): void {\n // Must have at least one auth method. An admin key alone is enough: the\n // /admin/* endpoints authenticate with X-Admin-Key only, so an admin-only\n // client (`client.admin.*`) is legitimate.\n if (!config.apiKey && !config.accessToken && !config.adminKey) {\n throw new Error(\n \"SpooledClient requires either apiKey or accessToken for authentication (or adminKey for admin-only use)\",\n );\n }\n\n // Validate API key format if provided\n // Accept both sp_ (new standard) and sk_ (legacy) prefixes\n if (\n config.apiKey &&\n !config.apiKey.startsWith(\"sp_\") &&\n !config.apiKey.startsWith(\"sk_\")\n ) {\n throw new Error(\n \"Invalid API key format. API keys should start with sp_live_, sp_test_, sk_live_, or sk_test_\",\n );\n }\n\n // Validate baseUrl\n if (\n !config.baseUrl.startsWith(\"http://\") &&\n !config.baseUrl.startsWith(\"https://\")\n ) {\n throw new Error(\"baseUrl must start with http:// or https://\");\n }\n\n // Validate timeout\n if (config.timeout <= 0) {\n throw new Error(\"timeout must be a positive number\");\n }\n\n // Validate retry config\n if (config.retry.maxRetries < 0) {\n throw new Error(\"retry.maxRetries must be non-negative\");\n }\n if (config.retry.baseDelay <= 0) {\n throw new Error(\"retry.baseDelay must be positive\");\n }\n if (config.retry.maxDelay < config.retry.baseDelay) {\n throw new Error(\"retry.maxDelay must be >= retry.baseDelay\");\n }\n if (config.retry.factor < 1) {\n throw new Error(\"retry.factor must be >= 1\");\n }\n\n // Validate circuit breaker config\n if (config.circuitBreaker.enabled) {\n if (config.circuitBreaker.failureThreshold <= 0) {\n throw new Error(\"circuitBreaker.failureThreshold must be positive\");\n }\n if (config.circuitBreaker.successThreshold <= 0) {\n throw new Error(\"circuitBreaker.successThreshold must be positive\");\n }\n if (config.circuitBreaker.timeout <= 0) {\n throw new Error(\"circuitBreaker.timeout must be positive\");\n }\n }\n}\n","/**\n * Custom Error Classes\n *\n * Provides a hierarchy of error types for the Spooled SDK.\n */\n\n/** Error response body from the API */\nexport interface ApiErrorBody {\n code: string;\n message: string;\n details?: Record<string, unknown>;\n}\n\n/**\n * Rate limit information parsed from headers.\n *\n * Authenticated responses that went through the plan rate limiter carry\n * `X-RateLimit-Limit`, `-Remaining`, `-Reset` and `-Scope` (API 0.1.122+); a\n * 429 adds `Retry-After`. Every field is optional: the headers are left out\n * when no rate-limit check ran (public and admin routes, a server without\n * Redis, older servers).\n */\nexport interface RateLimitInfo {\n /**\n * The limit the other fields describe: the plan burst (organization token\n * bucket) or an API key's own requests per minute.\n */\n limit?: number;\n /** Whole requests left after this one */\n remaining?: number;\n /**\n * When `remaining` next goes up (`X-RateLimit-Reset`, a Unix time in\n * seconds; the current time while the bucket is full).\n */\n reset?: Date;\n /** Seconds to wait before retrying (`Retry-After`, on a 429) */\n retryAfter?: number;\n /**\n * Which limit the headers describe (`X-RateLimit-Scope`): `organization`\n * (the plan's token bucket) or `api_key` (the key's `rateLimit`).\n */\n scope?: \"organization\" | \"api_key\" | (string & {});\n}\n\n/**\n * Base error class for all Spooled SDK errors\n */\nexport class SpooledError extends Error {\n /** HTTP status code (if applicable) */\n readonly statusCode: number;\n /** Error code from API response */\n readonly code: string;\n /** Additional error details */\n readonly details?: Record<string, unknown>;\n /** Request ID for debugging */\n readonly requestId?: string;\n /** Original cause of the error */\n readonly cause?: Error;\n\n constructor(\n message: string,\n statusCode: number = 0,\n code: string = \"UNKNOWN_ERROR\",\n details?: Record<string, unknown>,\n requestId?: string,\n cause?: Error,\n ) {\n super(message);\n this.name = \"SpooledError\";\n this.statusCode = statusCode;\n this.code = code;\n this.details = details;\n this.requestId = requestId;\n this.cause = cause;\n\n // Maintain proper stack trace in V8 environments\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n /**\n * Whether this error is retryable.\n *\n * Only 408 (Request Timeout) is retryable among the plain 4xx statuses: the\n * server gave up waiting for the request, so it never ran. Subclasses\n * override this (5xx, network, timeout, rate limit).\n */\n isRetryable(): boolean {\n return this.statusCode === 408;\n }\n\n /** Convert to plain object for logging */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n statusCode: this.statusCode,\n code: this.code,\n details: this.details,\n requestId: this.requestId,\n };\n }\n}\n\n/**\n * Authentication error (401)\n * Thrown when authentication fails (invalid/expired token or API key)\n */\nexport class AuthenticationError extends SpooledError {\n constructor(\n message: string = \"Authentication failed\",\n code: string = \"AUTHENTICATION_FAILED\",\n details?: Record<string, unknown>,\n requestId?: string,\n ) {\n super(message, 401, code, details, requestId);\n this.name = \"AuthenticationError\";\n }\n}\n\n/**\n * Authorization error (403)\n * Thrown when the authenticated user lacks permission\n */\nexport class AuthorizationError extends SpooledError {\n constructor(\n message: string = \"Access denied\",\n code: string = \"ACCESS_DENIED\",\n details?: Record<string, unknown>,\n requestId?: string,\n ) {\n super(message, 403, code, details, requestId);\n this.name = \"AuthorizationError\";\n }\n}\n\n/**\n * Not found error (404)\n * Thrown when a requested resource doesn't exist\n */\nexport class NotFoundError extends SpooledError {\n constructor(\n message: string = \"Resource not found\",\n code: string = \"NOT_FOUND\",\n details?: Record<string, unknown>,\n requestId?: string,\n ) {\n super(message, 404, code, details, requestId);\n this.name = \"NotFoundError\";\n }\n}\n\n/**\n * Conflict error (409)\n * Thrown when there's a conflict (e.g., duplicate resource)\n */\nexport class ConflictError extends SpooledError {\n constructor(\n message: string = \"Conflict\",\n code: string = \"CONFLICT\",\n details?: Record<string, unknown>,\n requestId?: string,\n ) {\n super(message, 409, code, details, requestId);\n this.name = \"ConflictError\";\n }\n}\n\n/**\n * Validation error (400 or 422)\n * Thrown when request validation fails.\n *\n * The API answers a field-rule failure (length, range) with 400 but a missing\n * or mistyped JSON field with 422; both are the caller's request being invalid,\n * so both surface as this class. `statusCode` tells them apart.\n */\nexport class ValidationError extends SpooledError {\n constructor(\n message: string = \"Validation failed\",\n code: string = \"VALIDATION_ERROR\",\n details?: Record<string, unknown>,\n requestId?: string,\n statusCode: 400 | 422 = 400,\n ) {\n super(message, statusCode, code, details, requestId);\n this.name = \"ValidationError\";\n }\n}\n\n/**\n * Payload too large error (413)\n * Thrown when request body exceeds size limit\n */\nexport class PayloadTooLargeError extends SpooledError {\n constructor(\n message: string = \"Request payload too large\",\n code: string = \"PAYLOAD_TOO_LARGE\",\n details?: Record<string, unknown>,\n requestId?: string,\n ) {\n super(message, 413, code, details, requestId);\n this.name = \"PayloadTooLargeError\";\n }\n}\n\n/** Plan-limit wording the API uses (\"Daily job limit reached\", \"queues limit reached (5/5)\"). */\nconst QUOTA_MESSAGE = /\\blimit reached\\b/i;\n\n/**\n * Rate limit error (429)\n * Thrown when rate limit is exceeded, or a plan quota is (see `isQuota`)\n */\nexport class RateLimitError extends SpooledError {\n /** Rate limit information */\n readonly rateLimitInfo: RateLimitInfo;\n\n constructor(\n message: string = \"Rate limit exceeded\",\n code: string = \"RATE_LIMIT_EXCEEDED\",\n rateLimitInfo: RateLimitInfo = {},\n details?: Record<string, unknown>,\n requestId?: string,\n ) {\n super(message, 429, code, details, requestId);\n this.name = \"RateLimitError\";\n this.rateLimitInfo = rateLimitInfo;\n }\n\n /**\n * True when this 429 is a plan quota or limit (daily job cap, active jobs,\n * queue/worker/webhook caps) rather than per-second rate limiting.\n *\n * A quota does not clear for minutes or hours, so retrying it only blocks the\n * caller for the whole backoff and, via the circuit breaker, takes every\n * other call on the client down with it. It is never retried and never\n * counted as a circuit breaker failure.\n *\n * Detection: the `QUOTA_EXCEEDED` code, or, for older plan-limit paths that\n * answer with plain text wrapped as `RATE_LIMIT_EXCEEDED`, a \"... limit\n * reached\" message that carries no `Retry-After`.\n */\n get isQuota(): boolean {\n if (this.code === \"QUOTA_EXCEEDED\") {\n return true;\n }\n return (\n this.rateLimitInfo.retryAfter === undefined &&\n QUOTA_MESSAGE.test(this.message)\n );\n }\n\n override isRetryable(): boolean {\n return !this.isQuota;\n }\n\n /** Get the number of seconds to wait before retrying */\n getRetryAfter(): number {\n if (this.rateLimitInfo.retryAfter !== undefined) {\n return this.rateLimitInfo.retryAfter;\n }\n if (this.rateLimitInfo.reset) {\n const now = Date.now();\n const resetTime = this.rateLimitInfo.reset.getTime();\n return Math.max(0, Math.ceil((resetTime - now) / 1000));\n }\n return 60; // Default to 60 seconds\n }\n\n override toJSON(): Record<string, unknown> {\n return {\n ...super.toJSON(),\n rateLimitInfo: this.rateLimitInfo,\n };\n }\n}\n\n/**\n * Server error (5xx)\n * Thrown when the server encounters an error\n */\nexport class ServerError extends SpooledError {\n constructor(\n message: string = \"Server error\",\n statusCode: number = 500,\n code: string = \"SERVER_ERROR\",\n details?: Record<string, unknown>,\n requestId?: string,\n ) {\n super(message, statusCode, code, details, requestId);\n this.name = \"ServerError\";\n }\n\n override isRetryable(): boolean {\n return true;\n }\n}\n\n/**\n * Network error\n * Thrown when a network request fails (no response received)\n */\nexport class NetworkError extends SpooledError {\n constructor(message: string = \"Network request failed\", cause?: Error) {\n super(message, 0, \"NETWORK_ERROR\", undefined, undefined, cause);\n this.name = \"NetworkError\";\n }\n\n override isRetryable(): boolean {\n return true;\n }\n}\n\n/**\n * Timeout error\n * Thrown when a request times out\n */\nexport class TimeoutError extends SpooledError {\n /** Timeout duration in milliseconds */\n readonly timeoutMs: number;\n\n constructor(message: string = \"Request timed out\", timeoutMs: number = 0) {\n super(message, 0, \"TIMEOUT\", { timeoutMs });\n this.name = \"TimeoutError\";\n this.timeoutMs = timeoutMs;\n }\n\n override isRetryable(): boolean {\n return true;\n }\n}\n\n/**\n * Circuit breaker open error\n * Thrown when the circuit breaker is open and rejecting requests\n */\nexport class CircuitBreakerOpenError extends SpooledError {\n constructor(message: string = \"Circuit breaker is open\") {\n super(message, 0, \"CIRCUIT_BREAKER_OPEN\");\n this.name = \"CircuitBreakerOpenError\";\n }\n\n override isRetryable(): boolean {\n return false; // Should wait for circuit to close\n }\n}\n\n/**\n * Unsupported operation error\n * Thrown by SDK methods whose route the Spooled API does not provide (or\n * always rejects). It is raised before any network call, so code that still\n * calls such a method fails loudly with an explanation instead of a 404.\n */\nexport class UnsupportedOperationError extends SpooledError {\n /** The SDK method that is not supported, e.g. `ingest.github` */\n readonly operation: string;\n\n constructor(operation: string, reason: string) {\n super(\n `${operation} is not supported by the Spooled API: ${reason}`,\n 0,\n \"UNSUPPORTED_OPERATION\",\n { operation },\n );\n this.name = \"UnsupportedOperationError\";\n this.operation = operation;\n }\n}\n\n/**\n * Parse rate limit headers from a Response\n */\nexport function parseRateLimitHeaders(headers: Headers): RateLimitInfo {\n const info: RateLimitInfo = {};\n\n const retryAfter = headers.get(\"Retry-After\");\n if (retryAfter) {\n const seconds = parseInt(retryAfter, 10);\n if (!isNaN(seconds)) {\n info.retryAfter = seconds;\n }\n }\n\n const limit = headers.get(\"X-RateLimit-Limit\");\n if (limit) {\n const parsed = parseInt(limit, 10);\n if (!isNaN(parsed)) {\n info.limit = parsed;\n }\n }\n\n const remaining = headers.get(\"X-RateLimit-Remaining\");\n if (remaining) {\n const parsed = parseInt(remaining, 10);\n if (!isNaN(parsed)) {\n info.remaining = parsed;\n }\n }\n\n const reset = headers.get(\"X-RateLimit-Reset\");\n if (reset) {\n const timestamp = parseInt(reset, 10);\n if (!isNaN(timestamp)) {\n info.reset = new Date(timestamp * 1000);\n }\n }\n\n const scope = headers.get(\"X-RateLimit-Scope\");\n if (scope) {\n info.scope = scope.trim();\n }\n\n return info;\n}\n\n/** Cap a raw (non-JSON) error body so a stray HTML page can't become a huge message. */\nconst MAX_RAW_ERROR_BODY_CHARS = 500;\n\n/**\n * Parse an error response body.\n *\n * Reads the body once as text, then:\n * - if it parses as a JSON object, extracts `{code, message}` (falling back to\n * the `error` field when `message` is absent);\n * - otherwise (plain-text/HTML body, or malformed JSON) preserves the raw body\n * text as the message so a server's human-readable error — e.g. a proxy's\n * `502 Bad Gateway` page — is not silently discarded.\n */\nasync function parseErrorBody(\n response: Response,\n): Promise<ApiErrorBody | null> {\n const contentType = response.headers.get(\"Content-Type\") || \"\";\n\n let raw: string;\n try {\n raw = await response.text();\n } catch {\n return null;\n }\n\n if (contentType.includes(\"application/json\")) {\n try {\n const body = JSON.parse(raw) as Record<string, unknown>;\n if (typeof body === \"object\" && body !== null) {\n // Error bodies come in two shapes: {code, message} or {error, code, details}.\n // Fall back to `error` when `message` is absent so the server's\n // human-readable message is not lost.\n const message =\n ((body.message as string) ?? (body.error as string)) ||\n response.statusText;\n return {\n code: (body.code as string) || \"UNKNOWN_ERROR\",\n message,\n details: body.details as Record<string, unknown> | undefined,\n };\n }\n } catch {\n // Content-Type claimed JSON but the body did not parse — fall through and\n // preserve the raw text below instead of throwing it away.\n }\n }\n\n // Non-JSON body (or unparseable JSON): keep the raw text as the message.\n const trimmed = raw.trim();\n if (trimmed) {\n const message =\n trimmed.length > MAX_RAW_ERROR_BODY_CHARS\n ? `${trimmed.slice(0, MAX_RAW_ERROR_BODY_CHARS)}…`\n : trimmed;\n return { code: \"UNKNOWN_ERROR\", message };\n }\n\n return null;\n}\n\n/**\n * Create an appropriate error from an HTTP response\n */\nexport async function createErrorFromResponse(\n response: Response,\n): Promise<SpooledError> {\n const requestId = response.headers.get(\"X-Request-ID\") ?? undefined;\n const body = await parseErrorBody(response);\n\n const message =\n body?.message || response.statusText || `HTTP ${response.status}`;\n const code = body?.code || \"UNKNOWN_ERROR\";\n const details = body?.details;\n\n switch (response.status) {\n case 400:\n return new ValidationError(message, code, details, requestId);\n\n // A missing or mistyped JSON field is a 422 from the API's extractor; it is\n // the same class of caller error as a 400 field-rule failure.\n case 422:\n return new ValidationError(message, code, details, requestId, 422);\n\n case 401:\n return new AuthenticationError(message, code, details, requestId);\n\n case 403:\n return new AuthorizationError(message, code, details, requestId);\n\n case 404:\n return new NotFoundError(message, code, details, requestId);\n\n case 409:\n return new ConflictError(message, code, details, requestId);\n\n case 413:\n return new PayloadTooLargeError(message, code, details, requestId);\n\n case 429: {\n const rateLimitInfo = parseRateLimitHeaders(response.headers);\n return new RateLimitError(\n message,\n code,\n rateLimitInfo,\n details,\n requestId,\n );\n }\n\n default:\n if (response.status >= 500) {\n return new ServerError(\n message,\n response.status,\n code,\n details,\n requestId,\n );\n }\n return new SpooledError(\n message,\n response.status,\n code,\n details,\n requestId,\n );\n }\n}\n\n/**\n * Check if an error is a SpooledError instance\n */\nexport function isSpooledError(error: unknown): error is SpooledError {\n return error instanceof SpooledError;\n}\n\n/**\n * Check if an error is retryable\n */\nexport function isRetryableError(error: unknown): boolean {\n if (error instanceof SpooledError) {\n return error.isRetryable();\n }\n // Network errors from fetch are typically retryable\n if (error instanceof TypeError) {\n return true;\n }\n return false;\n}\n","/**\n * Case Conversion Utilities\n *\n * Provides deep conversion between snake_case (API) and camelCase (SDK).\n * User-defined JSON blobs are preserved without conversion.\n */\n\n/**\n * Keys that should NOT have their values deeply converted.\n * These typically contain user-defined JSON that shouldn't be modified.\n */\nexport const SKIP_CONVERSION_KEYS = new Set([\n \"payload\",\n \"result\",\n \"metadata\",\n \"tags\",\n \"settings\",\n \"details\",\n \"extra\",\n \"payloadTemplate\",\n \"payload_template\",\n \"customLimits\",\n \"custom_limits\",\n]);\n\n/**\n * Check if a value is a plain object (not array, Date, null, etc.)\n */\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n !(value instanceof Date) &&\n !(value instanceof RegExp) &&\n Object.prototype.toString.call(value) === \"[object Object]\"\n );\n}\n\n/**\n * Convert a string from camelCase to snake_case\n */\nexport function camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * Convert a string from snake_case to camelCase\n */\nexport function snakeToCamel(str: string): string {\n // Handle numeric segments like `completed_24h` -> `completed24h`\n // and then standard `_x` -> `X` conversion.\n return str\n .replace(/_([0-9]+)/g, (_, digits) => digits)\n .replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n}\n\n/**\n * Deep convert object keys from camelCase to snake_case.\n * Preserves values in SKIP_CONVERSION_KEYS without deep conversion.\n *\n * @param obj - Object to convert\n * @param skipDeepConversion - Whether current context should skip deep conversion of values\n * @returns Object with snake_case keys\n */\nexport function toSnakeCase<T = unknown>(\n obj: T,\n skipDeepConversion = false,\n): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => toSnakeCase(item, skipDeepConversion)) as T;\n }\n\n if (obj instanceof Date) {\n return obj.toISOString() as T;\n }\n\n if (!isPlainObject(obj)) {\n return obj;\n }\n\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const snakeKey = camelToSnake(key);\n\n // Check if this key's value should skip deep conversion\n const shouldSkip =\n skipDeepConversion ||\n SKIP_CONVERSION_KEYS.has(key) ||\n SKIP_CONVERSION_KEYS.has(snakeKey);\n\n if (shouldSkip) {\n // Don't convert the value, just preserve it as-is\n result[snakeKey] = value;\n } else {\n // Recursively convert the value\n result[snakeKey] = toSnakeCase(value, false);\n }\n }\n\n return result as T;\n}\n\n/**\n * Deep convert object keys from snake_case to camelCase.\n * Preserves values in SKIP_CONVERSION_KEYS without deep conversion.\n *\n * @param obj - Object to convert\n * @param skipDeepConversion - Whether current context should skip deep conversion of values\n * @returns Object with camelCase keys\n */\nexport function toCamelCase<T = unknown>(\n obj: T,\n skipDeepConversion = false,\n): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => toCamelCase(item, skipDeepConversion)) as T;\n }\n\n if (obj instanceof Date) {\n return obj as T;\n }\n\n if (!isPlainObject(obj)) {\n return obj;\n }\n\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const camelKey = snakeToCamel(key);\n\n // Check if this key's value should skip deep conversion\n const shouldSkip =\n skipDeepConversion ||\n SKIP_CONVERSION_KEYS.has(key) ||\n SKIP_CONVERSION_KEYS.has(camelKey);\n\n if (shouldSkip) {\n // Don't convert the value, just preserve it as-is\n result[camelKey] = value;\n } else {\n // Recursively convert the value\n result[camelKey] = toCamelCase(value, false);\n }\n }\n\n return result as T;\n}\n\n/**\n * Convert request body from camelCase (SDK) to snake_case (API)\n */\nexport function convertRequest<T>(body: T): T {\n return toSnakeCase(body);\n}\n\n/**\n * Convert response body from snake_case (API) to camelCase (SDK)\n */\nexport function convertResponse<T>(body: T): T {\n return toCamelCase(body);\n}\n\n/**\n * Convert query parameters from camelCase to snake_case.\n * Only converts top-level keys, not nested objects.\n */\nexport function convertQueryParams(\n params: Record<string, string | number | boolean | undefined>,\n): Record<string, string> {\n const result: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n const snakeKey = camelToSnake(key);\n result[snakeKey] = String(value);\n }\n }\n\n return result;\n}\n","/**\n * Retry Utility\n *\n * Implements exponential backoff with jitter for retrying failed requests.\n */\n\nimport type { RetryConfig } from \"../config.js\";\nimport { RateLimitError, isRetryableError } from \"../errors.js\";\n\n/** Options for a single retry operation */\nexport interface RetryOptions {\n /** Retry configuration */\n config: RetryConfig;\n /** Optional abort signal to cancel retries */\n signal?: AbortSignal;\n /** Callback for retry events (for logging/debugging) */\n onRetry?: (attempt: number, error: Error, delayMs: number) => void;\n}\n\n/**\n * Calculate delay for a given attempt using exponential backoff with optional jitter\n *\n * @param attempt - Current attempt number (1-based)\n * @param config - Retry configuration\n * @param retryAfterSeconds - Optional Retry-After header value\n * @returns Delay in milliseconds\n */\nexport function calculateDelay(\n attempt: number,\n config: RetryConfig,\n retryAfterSeconds?: number,\n): number {\n // If we have a Retry-After value, use it (but respect maxDelay)\n if (retryAfterSeconds !== undefined && retryAfterSeconds > 0) {\n const retryAfterMs = retryAfterSeconds * 1000;\n return Math.min(retryAfterMs, config.maxDelay);\n }\n\n // Calculate exponential delay: baseDelay * factor^(attempt-1)\n const exponentialDelay =\n config.baseDelay * Math.pow(config.factor, attempt - 1);\n\n // Cap at maxDelay\n let delay = Math.min(exponentialDelay, config.maxDelay);\n\n // Add jitter if enabled (random value between 0 and 25% of delay)\n if (config.jitter) {\n const jitterRange = delay * 0.25;\n const jitter = Math.random() * jitterRange;\n delay = delay + jitter;\n }\n\n return Math.floor(delay);\n}\n\n/**\n * Check if an error should be retried\n *\n * @param error - The error to check\n * @param attempt - Current attempt number\n * @param config - Retry configuration\n * @returns Whether the error is retryable\n */\nexport function shouldRetry(\n error: Error,\n attempt: number,\n config: RetryConfig,\n): boolean {\n // Don't retry if we've exhausted attempts\n // attempt is 1-based, so with maxRetries=2, we allow attempts 1, 2, 3 (initial + 2 retries)\n if (attempt > config.maxRetries) {\n return false;\n }\n\n // Use custom retry function if provided\n if (config.retryOn) {\n return config.retryOn(error, attempt);\n }\n\n // Default: retry on retryable errors\n return isRetryableError(error);\n}\n\n/**\n * Sleep for the specified duration\n *\n * @param ms - Duration in milliseconds\n * @param signal - Optional abort signal\n * @returns Promise that resolves after the delay or rejects if aborted\n */\nexport function sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n return;\n }\n\n const timeoutId = setTimeout(() => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n\n const onAbort = () => {\n clearTimeout(timeoutId);\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n };\n\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\n/**\n * Execute a function with retry logic\n *\n * @param fn - Async function to execute\n * @param options - Retry options\n * @returns Promise resolving to the function result\n * @throws Last error if all retries fail\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: RetryOptions,\n): Promise<T> {\n const { config, signal, onRetry } = options;\n let lastError: Error | undefined;\n\n for (let attempt = 1; attempt <= config.maxRetries + 1; attempt++) {\n // Check if aborted before each attempt\n if (signal?.aborted) {\n throw new DOMException(\"Aborted\", \"AbortError\");\n }\n\n try {\n return await fn();\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n lastError = err;\n\n // Check if we should retry\n if (!shouldRetry(err, attempt, config)) {\n throw err;\n }\n\n // Calculate delay\n let retryAfter: number | undefined;\n if (err instanceof RateLimitError) {\n retryAfter = err.getRetryAfter();\n }\n const delayMs = calculateDelay(attempt, config, retryAfter);\n\n // Notify about retry\n onRetry?.(attempt, err, delayMs);\n\n // Wait before retrying\n await sleep(delayMs, signal);\n }\n }\n\n // Should not reach here, but throw last error just in case\n throw lastError ?? new Error(\"Retry failed with unknown error\");\n}\n\n/**\n * Create a retry wrapper with pre-configured options\n *\n * @param config - Retry configuration\n * @returns Function to wrap async operations with retry logic\n */\nexport function createRetryWrapper(config: RetryConfig) {\n return function retry<T>(\n fn: () => Promise<T>,\n options?: Partial<Omit<RetryOptions, \"config\">>,\n ): Promise<T> {\n return withRetry(fn, {\n config,\n ...options,\n });\n };\n}\n","/**\n * JSON parsing for API responses.\n *\n * `JSON.parse` (and `response.json()`) turns every number into a float64, so\n * an integer above 2^53 is silently changed: 1234567890123456789 arrives as\n * 1234567890123456768. User-owned JSON (payload, result, tags, and the other\n * {@link SKIP_CONVERSION_KEYS}) keeps those integers as decimal strings, which\n * are already a {@link JsonValue}. Numbers a float64 holds exactly, including\n * 2^53 itself, stay numbers. Typed counters outside those blobs are left\n * alone, so a field declared as `number` does not change type.\n */\n\nimport { SKIP_CONVERSION_KEYS } from \"./casing.js\";\n\n/** 2^53. Every integer with a smaller magnitude is exactly a float64. */\nconst TWO_POW_53 = \"9007199254740992\";\n\n/**\n * Parse an API JSON body, preserving integers above 2^53 inside user JSON.\n * Throws `SyntaxError` on malformed JSON, as `JSON.parse` does.\n */\nexport function parseApiJson(text: string): unknown {\n return JSON.parse(preserveExactIntegers(text));\n}\n\nfunction magnitudeExceedsTwoPow53(digits: string): boolean {\n let start = 0;\n while (start < digits.length - 1 && digits.charCodeAt(start) === 48) {\n start++;\n }\n const len = digits.length - start;\n if (len !== TWO_POW_53.length) {\n return len > TWO_POW_53.length;\n }\n for (let i = 0; i < len; i++) {\n const digit = digits.charCodeAt(start + i);\n const limit = TWO_POW_53.charCodeAt(i);\n if (digit !== limit) {\n return digit > limit;\n }\n }\n // Equal to 2^53, which float64 represents exactly.\n return false;\n}\n\ninterface Frame {\n kind: \"object\" | \"array\";\n /** This container is itself inside a user-JSON value. */\n exact: boolean;\n expect: \"key\" | \"colon\" | \"value\" | \"after\";\n /** The object key just read names a user-JSON blob. */\n keyIsExact: boolean;\n}\n\n/** True when the value about to be read must keep oversized integers. */\nfunction inExactValue(frames: Frame[]): boolean {\n const top = frames[frames.length - 1];\n if (!top || top.expect !== \"value\") {\n return false;\n }\n return top.exact || top.keyIsExact;\n}\n\n/**\n * Rewrite integer literals above 2^53 that sit inside user JSON so that a\n * following `JSON.parse` cannot round them. Everything else is copied through.\n * The rewrite has to happen on the text: a reviver already receives the\n * rounded number.\n */\nfunction preserveExactIntegers(text: string): string {\n const out: string[] = [];\n const frames: Frame[] = [];\n const n = text.length;\n let i = 0;\n\n const valueEnded = (): void => {\n const top = frames[frames.length - 1];\n if (top) {\n top.expect = \"after\";\n }\n };\n\n while (i < n) {\n const c = text[i];\n\n if (c === \" \" || c === \"\\n\" || c === \"\\r\" || c === \"\\t\") {\n out.push(c);\n i++;\n continue;\n }\n\n if (c === \"{\") {\n frames.push({\n kind: \"object\",\n exact: inExactValue(frames),\n expect: \"key\",\n keyIsExact: false,\n });\n out.push(c);\n i++;\n continue;\n }\n\n if (c === \"[\") {\n frames.push({\n kind: \"array\",\n exact: inExactValue(frames),\n expect: \"value\",\n keyIsExact: false,\n });\n out.push(c);\n i++;\n continue;\n }\n\n if (c === \"}\" || c === \"]\") {\n frames.pop();\n out.push(c);\n i++;\n valueEnded();\n continue;\n }\n\n if (c === \":\") {\n const top = frames[frames.length - 1];\n if (top && top.kind === \"object\") {\n top.expect = \"value\";\n }\n out.push(c);\n i++;\n continue;\n }\n\n if (c === \",\") {\n const top = frames[frames.length - 1];\n if (top) {\n top.expect = top.kind === \"object\" ? \"key\" : \"value\";\n top.keyIsExact = false;\n }\n out.push(c);\n i++;\n continue;\n }\n\n if (c === '\"') {\n const start = i;\n i++;\n while (i < n) {\n if (text[i] === \"\\\\\") {\n i++;\n if (i < n) i++;\n continue;\n }\n if (text[i] === '\"') {\n i++;\n break;\n }\n i++;\n }\n const raw = text.slice(start, i);\n const top = frames[frames.length - 1];\n if (top && top.kind === \"object\" && top.expect === \"key\") {\n let key = \"\";\n try {\n key = JSON.parse(raw) as string;\n } catch {\n key = \"\";\n }\n top.keyIsExact =\n typeof key === \"string\" && SKIP_CONVERSION_KEYS.has(key);\n top.expect = \"colon\";\n } else {\n valueEnded();\n }\n out.push(raw);\n continue;\n }\n\n if (c === \"-\" || (c >= \"0\" && c <= \"9\")) {\n const start = i;\n if (text[i] === \"-\") i++;\n const digitsAt = i;\n while (i < n && text[i] >= \"0\" && text[i] <= \"9\") i++;\n const digitsEnd = i;\n let isInteger = true;\n if (i < n && text[i] === \".\") {\n isInteger = false;\n i++;\n while (i < n && text[i] >= \"0\" && text[i] <= \"9\") i++;\n }\n if (i < n && (text[i] === \"e\" || text[i] === \"E\")) {\n isInteger = false;\n i++;\n if (i < n && (text[i] === \"+\" || text[i] === \"-\")) i++;\n while (i < n && text[i] >= \"0\" && text[i] <= \"9\") i++;\n }\n const raw = text.slice(start, i);\n const digits = text.slice(digitsAt, digitsEnd);\n if (\n isInteger &&\n digits.length > 0 &&\n inExactValue(frames) &&\n magnitudeExceedsTwoPow53(digits)\n ) {\n out.push(`\"${raw}\"`);\n } else {\n out.push(raw);\n }\n valueEnded();\n continue;\n }\n\n if (c >= \"a\" && c <= \"z\") {\n const start = i;\n while (i < n && text[i] >= \"a\" && text[i] <= \"z\") i++;\n out.push(text.slice(start, i));\n valueEnded();\n continue;\n }\n\n out.push(c);\n i++;\n }\n\n return out.join(\"\");\n}\n","/**\n * HTTP Client Utility\n *\n * Provides a fetch wrapper with:\n * - URL building and query string encoding\n * - JSON request/response handling\n * - Timeout support via AbortController\n * - Automatic retry with exponential backoff\n * - Circuit breaker protection\n * - Case conversion (camelCase <-> snake_case)\n */\n\nimport type { ResolvedConfig, DebugFn } from \"../config.js\";\nimport { API_BASE_PATH } from \"../config.js\";\nimport type { RetryConfig } from \"../config.js\";\nimport {\n createErrorFromResponse,\n NetworkError,\n parseRateLimitHeaders,\n RateLimitError,\n TimeoutError,\n SpooledError,\n type RateLimitInfo,\n} from \"../errors.js\";\nimport {\n convertRequest,\n convertResponse,\n convertQueryParams,\n} from \"./casing.js\";\nimport { withRetry } from \"./retry.js\";\nimport { CircuitBreaker } from \"./circuit-breaker.js\";\nimport { parseApiJson } from \"./json.js\";\n\n/**\n * HTTP methods considered idempotent per HTTP semantics.\n * Automatic retry on ambiguous failures (network/timeout/5xx) is only safe\n * for these; non-idempotent methods (POST/PATCH) may cause duplicate side\n * effects if retried after the request already reached the server.\n */\nconst IDEMPOTENT_METHODS = new Set<HttpMethod>([\"GET\", \"PUT\", \"DELETE\"]);\n\n/** HTTP methods */\nexport type HttpMethod = \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n\n/** Query parameters type */\nexport type QueryParams = Record<string, string | number | boolean | undefined>;\n\n/** Request options for HTTP client */\nexport interface HttpRequestOptions {\n /** HTTP method (default: GET) */\n method?: HttpMethod;\n /** Request body (will be JSON stringified) */\n body?: unknown;\n /**\n * Raw request body (sent as-is, not JSON stringified).\n * Use this for endpoints that require an exact byte payload (e.g. webhook signature verification).\n */\n rawBody?: string | Uint8Array | ArrayBuffer;\n /** Query parameters */\n params?: QueryParams;\n /**\n * Skip automatically prefixing the path with `/api/v1`.\n * Use this for top-level endpoints like `/health` or `/metrics`.\n */\n skipApiPrefix?: boolean;\n /** Additional headers */\n headers?: Record<string, string>;\n /** Request timeout in milliseconds (overrides client default) */\n timeout?: number;\n /** Whether to skip case conversion for request body */\n skipRequestConversion?: boolean;\n /** Whether to skip case conversion for response body */\n skipResponseConversion?: boolean;\n /** Whether to skip retry logic */\n skipRetry?: boolean;\n /**\n * The request is safe to replay even though it is a POST/PATCH, so network\n * errors, timeouts, 5xx and 408 are retried like they are for a GET.\n *\n * Use it only for calls the server makes idempotent: lease-fenced job and\n * worker acks (complete/fail/heartbeat answer a replay with 409) and job\n * creation with an idempotency key (the server returns the existing job).\n */\n idempotent?: boolean;\n /**\n * Never try to refresh the access token when this request gets a 401.\n * Set on the auth calls that the refresh itself makes.\n */\n skipAuthRefresh?: boolean;\n /** Optional abort signal */\n signal?: AbortSignal;\n}\n\n/** HTTP response wrapper */\nexport interface HttpResponse<T> {\n /** Response status code */\n status: number;\n /** Response headers */\n headers: Headers;\n /** Parsed response body */\n data: T;\n}\n\n/**\n * HTTP Client class\n *\n * Handles all HTTP communication with the Spooled API.\n */\nexport class HttpClient {\n private readonly config: ResolvedConfig;\n private readonly circuitBreaker: CircuitBreaker;\n private readonly debug: DebugFn | null;\n\n /** Current authentication token (API key or JWT) */\n private authToken: string | undefined;\n\n /** Optional function to mint a fresh access token (set when auto-refresh is enabled) */\n private refreshTokenFn: (() => Promise<string>) | null = null;\n\n /**\n * The refresh currently in flight, shared by every request that gets a 401\n * meanwhile. A boolean guard here made the second concurrent 401 skip the\n * refresh and fail even though the token was about to be replaced.\n */\n private refreshInFlight: Promise<boolean> | null = null;\n\n /** Rate-limit headers of the most recent response that carried them */\n private lastRateLimit: RateLimitInfo | undefined;\n\n constructor(config: ResolvedConfig, circuitBreaker: CircuitBreaker) {\n this.config = config;\n this.circuitBreaker = circuitBreaker;\n this.debug = config.debug;\n\n // Set initial auth token\n this.authToken = config.accessToken ?? config.apiKey;\n }\n\n /**\n * Set the authentication token\n */\n setAuthToken(token: string): void {\n this.authToken = token;\n }\n\n /**\n * The `X-RateLimit-*` (and `Retry-After`) values of the most recent\n * response that carried them, successful or not. `undefined` until such a\n * response arrives. With concurrent requests it is the last one to finish.\n */\n getLastRateLimitInfo(): RateLimitInfo | undefined {\n return this.lastRateLimit ? { ...this.lastRateLimit } : undefined;\n }\n\n /**\n * Set the token refresh function.\n *\n * When set, an expired-token 401 on the data plane triggers a single\n * refresh + retry of the original request with the new token.\n */\n setRefreshTokenFn(fn: () => Promise<string>): void {\n this.refreshTokenFn = fn;\n }\n\n /**\n * Refresh the access token once for all callers.\n *\n * Resolves true when a new token is installed, false when the refresh failed\n * (the caller then surfaces its original 401).\n */\n private refreshAuthToken(): Promise<boolean> {\n if (!this.refreshInFlight) {\n const refresh = this.refreshTokenFn!;\n this.refreshInFlight = (async () => {\n try {\n this.setAuthToken(await refresh());\n return true;\n } catch (refreshError) {\n const message =\n refreshError instanceof Error ? refreshError.message : \"unknown\";\n this.debug?.(\"Token refresh failed\", { error: message });\n return false;\n } finally {\n this.refreshInFlight = null;\n }\n })();\n }\n return this.refreshInFlight;\n }\n\n /**\n * Build full URL with query parameters\n */\n private buildUrl(\n path: string,\n params?: Record<string, string | number | boolean | undefined>,\n skipApiPrefix?: boolean,\n ): string {\n // Ensure path starts with /api/v1 unless explicitly skipped\n const fullPath = skipApiPrefix\n ? path\n : path.startsWith(\"/api/\")\n ? path\n : `${API_BASE_PATH}${path}`;\n const url = new URL(fullPath, this.config.baseUrl);\n\n if (params) {\n const convertedParams = convertQueryParams(params);\n for (const [key, value] of Object.entries(convertedParams)) {\n url.searchParams.append(key, value);\n }\n }\n\n return url.toString();\n }\n\n /**\n * Build request headers\n */\n private buildHeaders(customHeaders?: Record<string, string>): Headers {\n const headers = new Headers();\n\n // Add default headers\n for (const [key, value] of Object.entries(this.config.headers)) {\n headers.set(key, value);\n }\n\n // Add user agent\n headers.set(\"User-Agent\", this.config.userAgent);\n\n // Add auth token if available\n if (this.authToken) {\n headers.set(\"Authorization\", `Bearer ${this.authToken}`);\n }\n\n // Add custom headers\n if (customHeaders) {\n for (const [key, value] of Object.entries(customHeaders)) {\n headers.set(key, value);\n }\n }\n\n return headers;\n }\n\n /**\n * Execute a fetch request with timeout\n */\n private async fetchWithTimeout(\n url: string,\n init: RequestInit,\n timeoutMs: number,\n externalSignal?: AbortSignal,\n ): Promise<Response> {\n const controller = new AbortController();\n const { signal } = controller;\n\n // Link external signal to our controller\n if (externalSignal) {\n if (externalSignal.aborted) {\n controller.abort();\n } else {\n externalSignal.addEventListener(\"abort\", () => controller.abort(), {\n once: true,\n });\n }\n }\n\n // Set up timeout\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const response = await this.config.fetch(url, {\n ...init,\n signal,\n });\n return response;\n } catch (error) {\n if (error instanceof DOMException && error.name === \"AbortError\") {\n // Check if this was a timeout or user abort\n if (externalSignal?.aborted) {\n throw error; // User aborted\n }\n throw new TimeoutError(\n `Request timed out after ${timeoutMs}ms`,\n timeoutMs,\n );\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Execute a single HTTP request (no retry)\n */\n private async executeRequest<T>(\n url: string,\n options: HttpRequestOptions,\n hasRefreshed = false,\n ): Promise<HttpResponse<T>> {\n const method = options.method ?? \"GET\";\n // The token this attempt is sent with; a 401 for an older token than the\n // current one only needs a replay, not another refresh.\n const tokenUsed = this.authToken;\n const headers = this.buildHeaders(options.headers);\n const timeout = options.timeout ?? this.config.timeout;\n\n // Build request init\n const init: RequestInit = {\n method,\n headers,\n };\n\n // Add body for methods that support it\n if (method !== \"GET\") {\n if (options.rawBody !== undefined) {\n init.body = options.rawBody as unknown as RequestInit[\"body\"];\n } else if (options.body !== undefined) {\n const body = options.skipRequestConversion\n ? options.body\n : convertRequest(options.body);\n init.body = JSON.stringify(body);\n }\n }\n\n // The default `Content-Type: application/json` is only true when there is a\n // body. An empty body that claims to be JSON makes the API's optional-body\n // extractors (e.g. POST /queues/{name}/pause) fail with \"EOF while parsing\".\n if (init.body === undefined) {\n headers.delete(\"Content-Type\");\n }\n\n this.debug?.(`${method} ${url}`, { timeout, hasBody: !!options.body });\n\n let response: Response;\n try {\n response = await this.fetchWithTimeout(\n url,\n init,\n timeout,\n options.signal,\n );\n } catch (error) {\n if (error instanceof TimeoutError || error instanceof SpooledError) {\n throw error;\n }\n // Network error (fetch failed to get a response)\n const cause = error instanceof Error ? error : undefined;\n throw new NetworkError(\n `Network request failed: ${cause?.message ?? \"Unknown error\"}`,\n cause,\n );\n }\n\n this.debug?.(`Response: ${response.status}`, { url });\n\n this.recordRateLimit(response.headers);\n\n // Handle non-OK responses\n if (!response.ok) {\n // On an expired-token 401, refresh the access token (once, shared by\n // every concurrent request) and replay the original request. Replays are\n // limited to one per request, and the auth calls the refresh itself makes\n // are exempt, so a genuinely invalid credential can't loop.\n if (\n response.status === 401 &&\n this.refreshTokenFn &&\n !hasRefreshed &&\n !options.skipAuthRefresh\n ) {\n const alreadyRefreshed = this.authToken !== tokenUsed;\n if (alreadyRefreshed || (await this.refreshAuthToken())) {\n return this.executeRequest<T>(url, options, true);\n }\n }\n\n const apiError = await createErrorFromResponse(response);\n throw apiError;\n }\n\n // Parse response body\n let data: T;\n const contentType = response.headers.get(\"Content-Type\") || \"\";\n\n if (response.status === 204) {\n data = undefined as T;\n } else if (contentType.includes(\"application/json\")) {\n // response.json() parses every number as a float64, which changes an\n // integer above 2^53 before a job handler can see it. Parse the text so\n // those integers stay exact inside payload/result (and the other\n // free-form fields) and arrive as decimal strings.\n const rawData = parseApiJson(await response.text()) as T;\n data = options.skipResponseConversion\n ? rawData\n : convertResponse(rawData);\n } else {\n // Non-JSON response (e.g. Prometheus metrics text)\n data = (await response.text()) as unknown as T;\n }\n\n return {\n status: response.status,\n headers: response.headers,\n data,\n };\n }\n\n /** Remember the rate-limit headers of a response that has them. */\n private recordRateLimit(headers: Headers | undefined): void {\n if (\n !headers ||\n typeof headers.get !== \"function\" ||\n (headers.get(\"X-RateLimit-Limit\") === null &&\n headers.get(\"X-RateLimit-Remaining\") === null)\n ) {\n return;\n }\n this.lastRateLimit = parseRateLimitHeaders(headers);\n }\n\n /**\n * Make an HTTP request with retry and circuit breaker\n */\n async request<T>(\n path: string,\n options: HttpRequestOptions = {},\n ): Promise<HttpResponse<T>> {\n const url = this.buildUrl(path, options.params, options.skipApiPrefix);\n const method = options.method ?? \"GET\";\n\n // Wrap in circuit breaker\n const execute = async (): Promise<HttpResponse<T>> => {\n return this.circuitBreaker.execute(() =>\n this.executeRequest<T>(url, options),\n );\n };\n\n // Apply retry logic if not skipped\n if (options.skipRetry) {\n return execute();\n }\n\n return withRetry(execute, {\n config: this.resolveRetryConfig(method, options),\n signal: options.signal,\n onRetry: (attempt, error, delayMs) => {\n this.debug?.(`Retry attempt ${attempt} after ${delayMs}ms`, {\n error: error.message,\n });\n },\n });\n }\n\n /**\n * Determine whether a request carries an idempotency key (making a\n * non-idempotent method safe to retry).\n */\n private hasIdempotencyKey(options: HttpRequestOptions): boolean {\n if (!options.headers) {\n return false;\n }\n return Object.keys(options.headers).some(\n (key) => key.toLowerCase() === \"idempotency-key\",\n );\n }\n\n /**\n * Resolve the retry configuration for a request.\n *\n * Idempotent methods (GET/PUT/DELETE), any request carrying an idempotency\n * key and any request marked `idempotent` retry normally. Non-idempotent\n * methods (POST/PATCH) otherwise must NOT be retried on ambiguous failures\n * (network/timeout/5xx) — doing so risks duplicate jobs, double claims,\n * etc. They are still retried on a rate-limit 429, which is rejected before\n * the server processes the request and is therefore side-effect-free. A\n * quota 429 is never retried: it does not clear for hours.\n */\n private resolveRetryConfig(\n method: HttpMethod,\n options: HttpRequestOptions,\n ): RetryConfig {\n const base = this.config.retry;\n\n if (\n options.idempotent ||\n IDEMPOTENT_METHODS.has(method) ||\n this.hasIdempotencyKey(options)\n ) {\n return base;\n }\n\n return {\n ...base,\n retryOn: (error, attempt) => {\n if (error instanceof RateLimitError) {\n if (error.isQuota) {\n return false;\n }\n return base.retryOn ? base.retryOn(error, attempt) : true;\n }\n return false;\n },\n };\n }\n\n /**\n * Make a GET request\n */\n async get<T>(\n path: string,\n options?: Omit<HttpRequestOptions, \"method\" | \"body\">,\n ): Promise<T> {\n const response = await this.request<T>(path, { ...options, method: \"GET\" });\n return response.data;\n }\n\n /**\n * Make a POST request\n */\n async post<T>(\n path: string,\n body?: unknown,\n options?: Omit<HttpRequestOptions, \"method\" | \"body\">,\n ): Promise<T> {\n const response = await this.request<T>(path, {\n ...options,\n method: \"POST\",\n body,\n });\n return response.data;\n }\n\n /**\n * Make a PUT request\n */\n async put<T>(\n path: string,\n body?: unknown,\n options?: Omit<HttpRequestOptions, \"method\" | \"body\">,\n ): Promise<T> {\n const response = await this.request<T>(path, {\n ...options,\n method: \"PUT\",\n body,\n });\n return response.data;\n }\n\n /**\n * Make a PATCH request\n */\n async patch<T>(\n path: string,\n body?: unknown,\n options?: Omit<HttpRequestOptions, \"method\" | \"body\">,\n ): Promise<T> {\n const response = await this.request<T>(path, {\n ...options,\n method: \"PATCH\",\n body,\n });\n return response.data;\n }\n\n /**\n * Make a DELETE request\n */\n async delete<T = void>(\n path: string,\n options?: Omit<HttpRequestOptions, \"method\" | \"body\">,\n ): Promise<T> {\n const response = await this.request<T>(path, {\n ...options,\n method: \"DELETE\",\n });\n return response.data;\n }\n}\n\n/**\n * Create an HTTP client instance\n */\nexport function createHttpClient(\n config: ResolvedConfig,\n circuitBreaker: CircuitBreaker,\n): HttpClient {\n return new HttpClient(config, circuitBreaker);\n}\n","/**\n * Circuit Breaker Utility\n *\n * Implements the circuit breaker pattern to prevent cascading failures.\n * States: CLOSED (normal) -> OPEN (failing) -> HALF_OPEN (testing) -> CLOSED\n */\n\nimport type { CircuitBreakerConfig } from \"../config.js\";\nimport {\n CircuitBreakerOpenError,\n RateLimitError,\n isRetryableError,\n} from \"../errors.js\";\n\n/** Circuit breaker states */\nexport enum CircuitState {\n /** Normal operation - requests flow through */\n CLOSED = \"CLOSED\",\n /** Circuit is open - requests are rejected immediately */\n OPEN = \"OPEN\",\n /** Testing state - limited requests allowed to test recovery */\n HALF_OPEN = \"HALF_OPEN\",\n}\n\n/** Circuit breaker state change event */\nexport interface CircuitStateChange {\n from: CircuitState;\n to: CircuitState;\n timestamp: Date;\n failureCount: number;\n}\n\n/** Circuit breaker options */\nexport interface CircuitBreakerOptions extends CircuitBreakerConfig {\n /** Callback when state changes */\n onStateChange?: (event: CircuitStateChange) => void;\n /**\n * Custom function to determine if an error should count as a failure.\n * Defaults to {@link isCircuitBreakerFailure}.\n */\n isFailure?: (error: Error) => boolean;\n}\n\n/**\n * Default circuit breaker failure predicate.\n *\n * Counts the errors that say the API or the network is unhealthy: the\n * retryable ones (network errors, timeouts, 5xx, 408). A 429 never counts. A\n * rate-limit 429 is the API working as designed and telling this client to\n * slow down for `Retry-After` seconds; counting it let a burst above the plan\n * limit open the breaker and fail every call on the client for the breaker\n * timeout (30 s by default), including the retries that `Retry-After` had\n * already scheduled. The retry layer handles rate limiting on its own. A quota\n * 429 (`RateLimitError.isQuota`) was already excluded.\n */\nexport function isCircuitBreakerFailure(error: Error): boolean {\n if (error instanceof RateLimitError) {\n return false;\n }\n return isRetryableError(error);\n}\n\n/**\n * Circuit Breaker implementation\n *\n * Tracks failures and prevents requests when the failure threshold is reached.\n */\nexport class CircuitBreaker {\n private state: CircuitState = CircuitState.CLOSED;\n private failureCount = 0;\n private successCount = 0;\n private lastFailureTime: number = 0;\n private readonly config: CircuitBreakerOptions;\n\n constructor(config: CircuitBreakerOptions) {\n this.config = config;\n }\n\n /**\n * Get current circuit state\n */\n getState(): CircuitState {\n // Check if we should transition from OPEN to HALF_OPEN\n if (this.state === CircuitState.OPEN) {\n const now = Date.now();\n if (now - this.lastFailureTime >= this.config.timeout) {\n this.transitionTo(CircuitState.HALF_OPEN);\n }\n }\n return this.state;\n }\n\n /**\n * Check if circuit breaker is enabled\n */\n isEnabled(): boolean {\n return this.config.enabled;\n }\n\n /**\n * Check if requests are currently allowed\n */\n isAllowed(): boolean {\n if (!this.config.enabled) {\n return true;\n }\n\n const state = this.getState();\n return state === CircuitState.CLOSED || state === CircuitState.HALF_OPEN;\n }\n\n /**\n * Record a successful request\n */\n recordSuccess(): void {\n if (!this.config.enabled) {\n return;\n }\n\n if (this.state === CircuitState.HALF_OPEN) {\n this.successCount++;\n\n if (this.successCount >= this.config.successThreshold) {\n this.transitionTo(CircuitState.CLOSED);\n }\n } else if (this.state === CircuitState.CLOSED) {\n // Reset failure count on success in closed state\n this.failureCount = 0;\n }\n }\n\n /**\n * Record a failed request\n */\n recordFailure(error: Error): void {\n if (!this.config.enabled) {\n return;\n }\n\n // Check if this error should count as a failure. Call a caller predicate\n // as a method of its options, as 1.3.0 did, so one that reads `this` works.\n const shouldCount = this.config.isFailure\n ? this.config.isFailure(error)\n : isCircuitBreakerFailure(error);\n\n if (!shouldCount) {\n return;\n }\n\n this.lastFailureTime = Date.now();\n\n if (this.state === CircuitState.HALF_OPEN) {\n // Any failure in half-open state reopens the circuit\n this.transitionTo(CircuitState.OPEN);\n } else if (this.state === CircuitState.CLOSED) {\n this.failureCount++;\n\n if (this.failureCount >= this.config.failureThreshold) {\n this.transitionTo(CircuitState.OPEN);\n }\n }\n }\n\n /**\n * Transition to a new state\n */\n private transitionTo(newState: CircuitState): void {\n if (this.state === newState) {\n return;\n }\n\n const oldState = this.state;\n this.state = newState;\n\n // Reset counters on state change\n if (newState === CircuitState.CLOSED) {\n this.failureCount = 0;\n this.successCount = 0;\n } else if (newState === CircuitState.HALF_OPEN) {\n this.successCount = 0;\n } else if (newState === CircuitState.OPEN) {\n this.successCount = 0;\n }\n\n // Notify listener\n this.config.onStateChange?.({\n from: oldState,\n to: newState,\n timestamp: new Date(),\n failureCount: this.failureCount,\n });\n }\n\n /**\n * Reset the circuit breaker to closed state\n */\n reset(): void {\n this.state = CircuitState.CLOSED;\n this.failureCount = 0;\n this.successCount = 0;\n this.lastFailureTime = 0;\n }\n\n /**\n * Execute a function with circuit breaker protection\n *\n * @param fn - Async function to execute\n * @returns Promise resolving to the function result\n * @throws CircuitBreakerOpenError if circuit is open\n */\n async execute<T>(fn: () => Promise<T>): Promise<T> {\n if (!this.isAllowed()) {\n throw new CircuitBreakerOpenError(\n `Circuit breaker is open. Will retry after ${this.config.timeout}ms`,\n );\n }\n\n try {\n const result = await fn();\n this.recordSuccess();\n return result;\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.recordFailure(err);\n throw error;\n }\n }\n\n /**\n * Get circuit breaker statistics\n */\n getStats(): {\n state: CircuitState;\n failureCount: number;\n successCount: number;\n lastFailureTime: Date | null;\n config: CircuitBreakerConfig;\n } {\n return {\n state: this.getState(),\n failureCount: this.failureCount,\n successCount: this.successCount,\n lastFailureTime: this.lastFailureTime\n ? new Date(this.lastFailureTime)\n : null,\n config: {\n enabled: this.config.enabled,\n failureThreshold: this.config.failureThreshold,\n successThreshold: this.config.successThreshold,\n timeout: this.config.timeout,\n },\n };\n }\n}\n\n/**\n * Create a circuit breaker instance from configuration.\n *\n * Unless the config carries its own `isFailure`, rate-limit 429s do not count\n * as failures (the constructor defaults to {@link isCircuitBreakerFailure}).\n */\nexport function createCircuitBreaker(\n config: CircuitBreakerOptions,\n): CircuitBreaker {\n return new CircuitBreaker(config);\n}\n\n/**\n * Create a disabled circuit breaker (pass-through)\n */\nexport function createDisabledCircuitBreaker(): CircuitBreaker {\n return new CircuitBreaker({\n enabled: false,\n failureThreshold: 0,\n successThreshold: 0,\n timeout: 0,\n });\n}\n","/**\n * Auth Resource\n *\n * Handles authentication operations.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type {\n LoginParams,\n LoginResponse,\n RefreshTokenParams,\n RefreshTokenResponse,\n CurrentUserResponse,\n ValidateTokenParams,\n ValidateTokenResponse,\n StartEmailLoginResponse,\n CheckEmailResponse,\n} from \"../types/auth.js\";\n\nexport class AuthResource {\n constructor(\n private readonly http: HttpClient,\n /** Optional accessor for the client's current refresh token (used by logout) */\n private readonly getRefreshToken?: () => string | undefined,\n ) {}\n\n /**\n * Exchange API key for JWT tokens\n */\n async login(params: LoginParams): Promise<LoginResponse> {\n return this.http.post<LoginResponse>(\"/auth/login\", params, {\n skipAuthRefresh: true,\n });\n }\n\n /**\n * Refresh access token using refresh token\n */\n async refresh(params: RefreshTokenParams): Promise<RefreshTokenResponse> {\n // The refresh call is what a 401 triggers; a 401 on it must surface, not\n // wait on (or start) another refresh.\n return this.http.post<RefreshTokenResponse>(\"/auth/refresh\", params, {\n skipAuthRefresh: true,\n });\n }\n\n /**\n * Logout and revoke the refresh token server-side.\n *\n * The backend requires the refresh token in the body to invalidate the\n * session. When omitted, the client's current refresh token (if any) is\n * used automatically.\n */\n async logout(refreshToken?: string): Promise<void> {\n const token = refreshToken ?? this.getRefreshToken?.();\n await this.http.post<void>(\n \"/auth/logout\",\n token ? { refreshToken: token } : undefined,\n );\n }\n\n /**\n * Get current user/session info\n */\n async me(): Promise<CurrentUserResponse> {\n return this.http.get<CurrentUserResponse>(\"/auth/me\");\n }\n\n /**\n * Validate a token\n *\n * POST /auth/validate is `{ valid, error?, claims? }`. Claims use `org_id`\n * (camelCased `orgId`), not `organizationId`. Invalid tokens send `error`,\n * not `message`.\n */\n async validate(params: ValidateTokenParams): Promise<ValidateTokenResponse> {\n const raw = await this.http.post<RawValidateTokenResponse>(\n \"/auth/validate\",\n params,\n );\n return mapValidate(raw);\n }\n\n /**\n * Start email-based login flow (sends a 6-digit code)\n */\n async startEmailLogin(email: string): Promise<StartEmailLoginResponse> {\n return this.http.post<StartEmailLoginResponse>(\"/auth/email/start\", {\n email,\n });\n }\n\n /**\n * Check whether an email is registered (GET /auth/check-email)\n */\n async checkEmail(email: string): Promise<CheckEmailResponse> {\n return this.http.get<CheckEmailResponse>(\"/auth/check-email\", {\n params: { email },\n });\n }\n}\n\ninterface RawValidateTokenResponse {\n valid: boolean;\n message?: string;\n error?: string;\n claims?: {\n organizationId?: string;\n orgId?: string;\n apiKeyId?: string;\n queues?: string[];\n exp?: number;\n iat?: number;\n };\n}\n\nfunction mapValidate(raw: RawValidateTokenResponse): ValidateTokenResponse {\n const claims = raw.claims;\n const organizationId = claims?.organizationId ?? claims?.orgId;\n return {\n valid: raw.valid,\n message: raw.message ?? raw.error,\n error: raw.error ?? raw.message,\n claims: claims\n ? {\n organizationId: organizationId ?? \"\",\n orgId: claims.orgId ?? organizationId,\n apiKeyId: claims.apiKeyId ?? \"\",\n queues: claims.queues ?? [],\n exp: claims.exp ?? 0,\n iat: claims.iat ?? 0,\n }\n : undefined,\n };\n}\n","/**\n * Failure message coercion\n *\n * `POST /jobs/{id}/fail` rejects an empty or over-long `error` with a 400.\n * A worker that reported its failure with such text got nothing recorded: the\n * job stayed `processing` until its lease ran out, then ran again. The text of\n * a failure is therefore always made acceptable before it is sent.\n */\n\n/** Longest error text the API accepts (characters, not bytes). */\nexport const MAX_FAILURE_MESSAGE_CHARS = 2048;\n\n/** Text sent when a handler failed without saying why. */\nexport const DEFAULT_FAILURE_MESSAGE = \"Job failed\";\n\n/**\n * Make `message` acceptable to the fail endpoint: empty becomes\n * {@link DEFAULT_FAILURE_MESSAGE}; text over {@link MAX_FAILURE_MESSAGE_CHARS}\n * is cut to that many characters. The cut is by code point, so an emoji or\n * other astral character is never split into a lone surrogate.\n */\nexport function coerceFailureMessage(message: unknown): string {\n const text =\n typeof message === \"string\" ? message : message == null ? \"\" : `${message}`;\n if (text === \"\") {\n return DEFAULT_FAILURE_MESSAGE;\n }\n // UTF-16 length is an upper bound of the code point count: skip the\n // allocation for the common short message.\n if (text.length <= MAX_FAILURE_MESSAGE_CHARS) {\n return text;\n }\n const codePoints = Array.from(text);\n return codePoints.length <= MAX_FAILURE_MESSAGE_CHARS\n ? text\n : codePoints.slice(0, MAX_FAILURE_MESSAGE_CHARS).join(\"\");\n}\n","/**\n * Paging and query helpers shared by the list resources.\n */\n\n/** Response header that says whether another page follows (API 0.1.122+). */\nexport const HAS_MORE_HEADER = \"X-Has-More\";\n\n/**\n * Whether another page follows a list response.\n *\n * Reads `X-Has-More` when the server sends it. An older server does not, so\n * a page as long as the limit the server applied counts as \"maybe more\": the\n * caller asks once more and gets an empty page at the end.\n */\nexport function hasMoreFromHeaders(\n headers: Headers,\n count: number,\n limit: number | undefined,\n defaultLimit: number,\n maxLimit: number,\n): boolean {\n const header = headers.get(HAS_MORE_HEADER);\n if (header !== null) {\n return header.trim().toLowerCase() === \"true\";\n }\n const applied = Math.min(Math.max(limit ?? defaultLimit, 1), maxLimit);\n return count >= applied;\n}\n\n/**\n * A timestamp query parameter: a `Date` becomes an ISO 8601 UTC string\n * (RFC 3339); a string is sent as given.\n */\nexport function toQueryTimestamp(\n value: Date | string | undefined,\n): string | undefined {\n return value instanceof Date ? value.toISOString() : value;\n}\n","/**\n * Jobs Resource\n *\n * Handles job operations including worker processing endpoints.\n */\n\nimport type { HttpClient, QueryParams } from \"../utils/http.js\";\nimport { coerceFailureMessage } from \"../utils/failure.js\";\nimport { hasMoreFromHeaders, toQueryTimestamp } from \"../utils/paging.js\";\nimport type { ListPage } from \"../types/common.js\";\nimport type {\n Job,\n JobSummary,\n JobStats,\n CreateJobParams,\n CreateJobResult,\n JobHistoryEvent,\n JobHistoryParams,\n ListJobsParams,\n BatchJobStatus,\n ClaimJobsParams,\n ClaimJobsResult,\n CompleteJobParams,\n FailJobParams,\n HeartbeatJobParams,\n BoostPriorityResponse,\n BulkEnqueueParams,\n BulkEnqueueResponse,\n ListDlqParams,\n RetryDlqParams,\n RetryDlqResponse,\n PurgeDlqParams,\n PurgeDlqResponse,\n} from \"../types/jobs.js\";\n\n/** Default and largest page of `GET /jobs` and `GET /jobs/dlq`. */\nconst JOB_LIST_DEFAULT_LIMIT = 50;\nconst JOB_LIST_MAX_LIMIT = 100;\n/** Default and largest page of `GET /jobs/{id}/history`. */\nconst JOB_HISTORY_DEFAULT_LIMIT = 100;\nconst JOB_HISTORY_MAX_LIMIT = 500;\n\n/** DLQ operations */\nexport interface DlqOperations {\n /** List jobs in dead-letter queue */\n list(params?: ListDlqParams): Promise<JobSummary[]>;\n /**\n * List one page of the dead-letter queue with `hasMore` from the\n * `X-Has-More` header (API 0.1.122+).\n */\n listPage(params?: ListDlqParams): Promise<ListPage<JobSummary>>;\n /** Retry jobs from DLQ */\n retry(params: RetryDlqParams): Promise<RetryDlqResponse>;\n /** Purge jobs from DLQ */\n purge(params: PurgeDlqParams): Promise<PurgeDlqResponse>;\n}\n\nexport class JobsResource {\n /** Dead-letter queue operations */\n readonly dlq: DlqOperations;\n\n constructor(private readonly http: HttpClient) {\n this.dlq = {\n list: this.listDlq.bind(this),\n listPage: this.listDlqPage.bind(this),\n retry: this.retryDlq.bind(this),\n purge: this.purgeDlq.bind(this),\n };\n }\n\n /**\n * Create a new job\n */\n async create(params: CreateJobParams): Promise<CreateJobResult> {\n // With an idempotency key the server returns the existing job for a replay\n // (`created: false`), so a network error or 5xx can be retried safely.\n return this.http.post<CreateJobResult>(\"/jobs\", params, {\n idempotent: params.idempotencyKey ? true : undefined,\n });\n }\n\n /**\n * Create a job and return the full job object\n */\n async createAndGet(params: CreateJobParams): Promise<Job> {\n const result = await this.create(params);\n return this.get(result.id);\n }\n\n /**\n * List jobs with optional filtering\n *\n * `status` takes one status or several, and `q`, `jobType`, `createdAfter`\n * and `createdBefore` filter on the server (API 0.1.122+). Use\n * {@link JobsResource.listPage} to also learn whether another page follows.\n */\n async list(params?: ListJobsParams): Promise<JobSummary[]> {\n return (await this.listPage(params)).data;\n }\n\n /**\n * List one page of jobs with `hasMore` from the `X-Has-More` header\n * (API 0.1.122+). Takes the same filters as {@link JobsResource.list}.\n *\n * @example\n * ```typescript\n * let offset = 0;\n * for (;;) {\n * const page = await client.jobs.listPage({\n * status: [\"failed\", \"deadletter\"],\n * createdAfter: new Date(Date.now() - 86_400_000),\n * limit: 100,\n * offset,\n * });\n * handle(page.data);\n * if (!page.hasMore) break;\n * offset += page.data.length;\n * }\n * ```\n */\n async listPage(params?: ListJobsParams): Promise<ListPage<JobSummary>> {\n return this.listSummaries(\"/jobs\", params);\n }\n\n /**\n * Get a job by ID\n */\n async get(id: string): Promise<Job> {\n const job = await this.http.get<Job>(`/jobs/${id}`);\n return withJobType(job);\n }\n\n /**\n * Cancel a pending or scheduled job\n */\n async cancel(id: string): Promise<void> {\n await this.http.delete(`/jobs/${id}`);\n }\n\n /**\n * Retry a failed or dead-lettered job\n */\n async retry(id: string): Promise<Job> {\n const job = await this.http.post<Job>(`/jobs/${id}/retry`);\n return withJobType(job);\n }\n\n /**\n * Boost job priority\n */\n async boostPriority(\n id: string,\n priority: number,\n ): Promise<BoostPriorityResponse> {\n return this.http.put<BoostPriorityResponse>(`/jobs/${id}/priority`, {\n priority,\n });\n }\n\n /**\n * Get the recorded lifecycle events of a job (`GET /jobs/{id}/history`,\n * API 0.1.122+), oldest first unless `order: \"desc\"`.\n *\n * The history is sparse: the server records REST claims (`processing`),\n * completions (`completed`) and failures (`retry_scheduled`,\n * `deadlettered`) and the scheduler's dead-letter sweeps, so a job settled\n * over gRPC may have few or no events. An unknown job is a `NotFoundError`.\n */\n async history(\n id: string,\n params?: JobHistoryParams,\n ): Promise<JobHistoryEvent[]> {\n return (await this.historyPage(id, params)).data;\n }\n\n /**\n * One page of {@link JobsResource.history} with `hasMore` from the\n * `X-Has-More` header. `limit` defaults to 100 (at most 500).\n */\n async historyPage(\n id: string,\n params?: JobHistoryParams,\n ): Promise<ListPage<JobHistoryEvent>> {\n const response = await this.http.request<JobHistoryEvent[]>(\n `/jobs/${id}/history`,\n {\n method: \"GET\",\n params: {\n order: params?.order,\n limit: params?.limit,\n offset: params?.offset,\n },\n },\n );\n const data = response.data ?? [];\n return {\n data,\n hasMore: hasMoreFromHeaders(\n response.headers,\n data.length,\n params?.limit,\n JOB_HISTORY_DEFAULT_LIMIT,\n JOB_HISTORY_MAX_LIMIT,\n ),\n };\n }\n\n /**\n * Get job statistics\n */\n async getStats(): Promise<JobStats> {\n return this.http.get<JobStats>(\"/jobs/stats\");\n }\n\n /**\n * Get status of multiple jobs at once\n */\n async batchStatus(ids: string[]): Promise<BatchJobStatus[]> {\n if (ids.length === 0) {\n return [];\n }\n if (ids.length > 100) {\n throw new Error(\"Maximum 100 job IDs allowed per request\");\n }\n return this.http.get<BatchJobStatus[]>(\"/jobs/status\", {\n params: { ids: ids.join(\",\") },\n });\n }\n\n /**\n * Bulk enqueue multiple jobs\n */\n async bulkEnqueue(params: BulkEnqueueParams): Promise<BulkEnqueueResponse> {\n return this.http.post<BulkEnqueueResponse>(\"/jobs/bulk\", params);\n }\n\n // Worker processing endpoints\n\n /**\n * Claim jobs for worker processing\n */\n async claim(params: ClaimJobsParams): Promise<ClaimJobsResult> {\n return this.http.post<ClaimJobsResult>(\"/jobs/claim\", params);\n }\n\n /**\n * Complete a job (worker ack)\n *\n * Lease-fenced and idempotent on the server, so a network error, timeout or\n * 5xx is retried: a lost ack would otherwise re-run a finished job.\n */\n async complete(\n id: string,\n params: CompleteJobParams,\n ): Promise<{ success: boolean }> {\n return this.http.post<{ success: boolean }>(\n `/jobs/${id}/complete`,\n params,\n { idempotent: true },\n );\n }\n\n /**\n * Fail a job (worker nack)\n *\n * `params.error` is made acceptable first: empty text becomes \"Job failed\"\n * and text over 2048 characters is truncated, because the API rejects both\n * with a 400 that would leave the job processing until its lease expires.\n * Retried like {@link JobsResource.complete}.\n */\n async fail(\n id: string,\n params: FailJobParams,\n ): Promise<{ success: boolean; error?: string }> {\n return this.http.post<{ success: boolean; error?: string }>(\n `/jobs/${id}/fail`,\n { ...params, error: coerceFailureMessage(params.error) },\n { idempotent: true },\n );\n }\n\n /**\n * Extend job lease (heartbeat)\n *\n * Retried like {@link JobsResource.complete}: with the default 30 s lease and\n * 15 s heartbeat, one lost heartbeat leaves no slack.\n */\n async heartbeat(\n id: string,\n params: HeartbeatJobParams,\n ): Promise<{ success: boolean }> {\n return this.http.post<{ success: boolean }>(\n `/jobs/${id}/heartbeat`,\n params,\n { idempotent: true },\n );\n }\n\n // DLQ operations (private implementations)\n\n private async listDlq(params?: ListDlqParams): Promise<JobSummary[]> {\n return (await this.listDlqPage(params)).data;\n }\n\n private async listDlqPage(\n params?: ListDlqParams,\n ): Promise<ListPage<JobSummary>> {\n return this.listSummaries(\"/jobs/dlq\", params);\n }\n\n private async listSummaries(\n path: string,\n params?: ListJobsParams | ListDlqParams,\n ): Promise<ListPage<JobSummary>> {\n const response = await this.http.request<JobSummary[]>(path, {\n method: \"GET\",\n params: jobListQuery(params),\n });\n const rows = response.data ?? [];\n return {\n data: rows.map((row) => ({\n ...row,\n jobType: row.jobType ?? jobTypeFromPayload(row),\n })),\n hasMore: hasMoreFromHeaders(\n response.headers,\n rows.length,\n params?.limit,\n JOB_LIST_DEFAULT_LIMIT,\n JOB_LIST_MAX_LIMIT,\n ),\n };\n }\n\n private async retryDlq(params: RetryDlqParams): Promise<RetryDlqResponse> {\n return this.http.post<RetryDlqResponse>(\"/jobs/dlq/retry\", params);\n }\n\n private async purgeDlq(params: PurgeDlqParams): Promise<PurgeDlqResponse> {\n return this.http.post<PurgeDlqResponse>(\"/jobs/dlq/purge\", params);\n }\n}\n\n/**\n * Query string of a job list: a status list becomes `a,b` and a `Date` an\n * ISO 8601 string (`String(date)` is not RFC 3339 and the API answers 400).\n * Keys the types do not know are passed through as before.\n */\nfunction jobListQuery(\n params?: ListJobsParams | ListDlqParams,\n): QueryParams | undefined {\n if (!params) {\n return undefined;\n }\n const { status, createdAfter, createdBefore, ...rest } =\n params as ListJobsParams;\n let statusParam: string | undefined;\n if (typeof status === \"string\") {\n statusParam = status;\n } else if (status && status.length > 0) {\n statusParam = status.join(\",\");\n }\n return {\n ...(rest as QueryParams),\n status: statusParam,\n createdAfter: toQueryTimestamp(createdAfter),\n createdBefore: toQueryTimestamp(createdBefore),\n };\n}\n\nfunction withJobType<T extends { jobType?: string; payload?: unknown }>(\n job: T,\n): T {\n return {\n ...job,\n jobType: job.jobType ?? jobTypeFromPayload(job) ?? undefined,\n };\n}\n\nfunction jobTypeFromPayload(row: {\n jobType?: string;\n payload?: unknown;\n}): string | undefined {\n if (typeof row.jobType === \"string\" && row.jobType !== \"\") {\n return row.jobType;\n }\n const payload = row.payload;\n if (!payload || typeof payload !== \"object\" || Array.isArray(payload)) {\n return undefined;\n }\n const rec = payload as { jobType?: unknown; job_type?: unknown };\n for (const value of [rec.jobType, rec.job_type]) {\n if (typeof value === \"string\" && value !== \"\") {\n return value;\n }\n }\n return undefined;\n}\n","/**\n * Queues Resource\n *\n * Handles queue configuration and control operations.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type {\n QueueConfig,\n QueueConfigSummary,\n QueueStats,\n UpdateQueueConfigParams,\n PauseQueueResponse,\n ResumeQueueResponse,\n DeleteQueueOptions,\n} from \"../types/queues.js\";\n\nexport class QueuesResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all queues\n */\n async list(): Promise<QueueConfigSummary[]> {\n return this.http.get<QueueConfigSummary[]>(\"/queues\");\n }\n\n /**\n * Get queue configuration by name\n */\n async get(name: string): Promise<QueueConfig> {\n return this.http.get<QueueConfig>(`/queues/${encodeURIComponent(name)}`);\n }\n\n /**\n * Update queue configuration\n */\n async updateConfig(\n name: string,\n params: UpdateQueueConfigParams,\n ): Promise<QueueConfig> {\n return this.http.put<QueueConfig>(\n `/queues/${encodeURIComponent(name)}/config`,\n params,\n );\n }\n\n /**\n * Get queue statistics\n */\n async getStats(name: string): Promise<QueueStats> {\n return this.http.get<QueueStats>(\n `/queues/${encodeURIComponent(name)}/stats`,\n );\n }\n\n /**\n * Pause a queue\n */\n async pause(name: string, reason?: string): Promise<PauseQueueResponse> {\n return this.http.post<PauseQueueResponse>(\n `/queues/${encodeURIComponent(name)}/pause`,\n reason ? { reason } : undefined,\n );\n }\n\n /**\n * Resume a paused queue\n */\n async resume(name: string): Promise<ResumeQueueResponse> {\n return this.http.post<ResumeQueueResponse>(\n `/queues/${encodeURIComponent(name)}/resume`,\n );\n }\n\n /**\n * Delete a queue configuration\n *\n * Without `deleteJobs` the API only deletes an explicit queue config of an\n * idle queue, and answers 409 otherwise: a queue that exists only because\n * jobs were posted to it has no config to delete, and a queue with pending\n * or processing jobs is not idle. Pass `{ deleteJobs: true }` to delete the\n * queue's jobs (and DLQ rows) along with it.\n */\n async delete(name: string, options?: DeleteQueueOptions): Promise<void> {\n await this.http.delete(`/queues/${encodeURIComponent(name)}`, {\n params: options?.deleteJobs ? { deleteJobs: true } : undefined,\n });\n }\n}\n","/**\n * Workers Resource\n *\n * Handles worker registration and management.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type {\n Worker,\n WorkerSummary,\n RegisterWorkerParams,\n RegisterWorkerResponse,\n WorkerHeartbeatParams,\n} from \"../types/workers.js\";\n\nexport class WorkersResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all workers\n */\n async list(): Promise<WorkerSummary[]> {\n return this.http.get<WorkerSummary[]>(\"/workers\");\n }\n\n /**\n * Get a worker by ID\n */\n async get(id: string): Promise<Worker> {\n return this.http.get<Worker>(`/workers/${id}`);\n }\n\n /**\n * Register a new worker\n */\n async register(\n params: RegisterWorkerParams,\n ): Promise<RegisterWorkerResponse> {\n return this.http.post<RegisterWorkerResponse>(\"/workers/register\", params);\n }\n\n /**\n * Send worker heartbeat\n *\n * Idempotent on the server, so network errors, timeouts and 5xx are retried.\n */\n async heartbeat(id: string, params: WorkerHeartbeatParams): Promise<void> {\n await this.http.post(`/workers/${id}/heartbeat`, params, {\n idempotent: true,\n });\n }\n\n /**\n * Deregister a worker\n */\n async deregister(id: string): Promise<void> {\n await this.http.post(`/workers/${id}/deregister`);\n }\n}\n","/**\n * Schedules Resource\n *\n * Handles cron schedule operations.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type {\n Schedule,\n CreateScheduleParams,\n CreateScheduleResponse,\n UpdateScheduleParams,\n ListSchedulesParams,\n TriggerScheduleResponse,\n ScheduleRun,\n} from \"../types/schedules.js\";\n\nexport class SchedulesResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all schedules\n */\n async list(params?: ListSchedulesParams): Promise<Schedule[]> {\n return this.http.get<Schedule[]>(\"/schedules\", {\n params: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * Create a new schedule\n */\n async create(params: CreateScheduleParams): Promise<CreateScheduleResponse> {\n return this.http.post<CreateScheduleResponse>(\"/schedules\", params);\n }\n\n /**\n * Get a schedule by ID\n */\n async get(id: string): Promise<Schedule> {\n return this.http.get<Schedule>(`/schedules/${id}`);\n }\n\n /**\n * Update a schedule\n */\n async update(id: string, params: UpdateScheduleParams): Promise<Schedule> {\n return this.http.put<Schedule>(`/schedules/${id}`, params);\n }\n\n /**\n * Delete a schedule\n */\n async delete(id: string): Promise<void> {\n await this.http.delete(`/schedules/${id}`);\n }\n\n /**\n * Pause a schedule\n */\n async pause(id: string): Promise<Schedule> {\n return this.http.post<Schedule>(`/schedules/${id}/pause`);\n }\n\n /**\n * Resume a paused schedule\n */\n async resume(id: string): Promise<Schedule> {\n return this.http.post<Schedule>(`/schedules/${id}/resume`);\n }\n\n /**\n * Manually trigger a schedule\n */\n async trigger(id: string): Promise<TriggerScheduleResponse> {\n return this.http.post<TriggerScheduleResponse>(`/schedules/${id}/trigger`);\n }\n\n /**\n * Get schedule execution history\n */\n async getHistory(id: string, limit?: number): Promise<ScheduleRun[]> {\n return this.http.get<ScheduleRun[]>(`/schedules/${id}/history`, {\n params: limit ? { limit } : undefined,\n });\n }\n}\n","/**\n * Workflows Resource\n *\n * Handles workflow operations including job dependencies.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport { NotFoundError } from \"../errors.js\";\nimport type { JsonObject } from \"../types/common.js\";\nimport type {\n WorkflowResponse,\n CreateWorkflowParams,\n CreateWorkflowResponse,\n ListWorkflowsParams,\n JobWithDependencies,\n AddDependenciesParams,\n AddDependenciesResponse,\n WorkflowJob,\n WorkflowJobStatus,\n} from \"../types/workflows.js\";\n\n/** Workflow job operations */\nexport interface WorkflowJobOperations {\n /**\n * List all jobs in a workflow.\n *\n * @param workflowId - The workflow ID\n * @example\n * ```typescript\n * const jobs = await client.workflows.jobs.list('wf_123');\n * console.log('Jobs:', jobs.map(j => j.id));\n * ```\n */\n list(workflowId: string): Promise<WorkflowJob[]>;\n\n /**\n * Get a specific job within a workflow.\n *\n * @param workflowId - The workflow ID\n * @param jobId - The job ID\n * @example\n * ```typescript\n * const job = await client.workflows.jobs.get('wf_123', 'job_456');\n * console.log('Job status:', job.status);\n * ```\n */\n get(workflowId: string, jobId: string): Promise<WorkflowJob>;\n\n /**\n * Get the status of all jobs in a workflow.\n *\n * Returns a summary of each job's status. The API does not store or return\n * the `key` a job was created with, so `key` is undefined; map keys to job\n * IDs from the `jobIds` array that `workflows.create()` returns.\n *\n * @param workflowId - The workflow ID\n * @example\n * ```typescript\n * const statuses = await client.workflows.jobs.getStatus('wf_123');\n * for (const s of statuses) {\n * console.log(`${s.jobId}: ${s.status}`);\n * }\n * ```\n */\n getStatus(workflowId: string): Promise<WorkflowJobStatus[]>;\n\n /**\n * Get job dependencies.\n *\n * @param jobId - The job ID\n * @example\n * ```typescript\n * const deps = await client.workflows.jobs.getDependencies('job_456');\n * console.log('Depends on:', deps.dependencies);\n * ```\n */\n getDependencies(jobId: string): Promise<JobWithDependencies>;\n\n /**\n * Add dependencies to a job.\n *\n * @param jobId - The job ID\n * @param params - Dependencies to add\n * @example\n * ```typescript\n * await client.workflows.jobs.addDependencies('job_456', {\n * dependsOnJobIds: ['job_123'],\n * });\n * ```\n */\n addDependencies(\n jobId: string,\n params: AddDependenciesParams,\n ): Promise<AddDependenciesResponse>;\n}\n\nexport class WorkflowsResource {\n /** Workflow job operations */\n readonly jobs: WorkflowJobOperations;\n\n constructor(private readonly http: HttpClient) {\n this.jobs = {\n list: this.listWorkflowJobs.bind(this),\n get: this.getWorkflowJob.bind(this),\n getStatus: this.getWorkflowJobsStatus.bind(this),\n getDependencies: this.getJobDependencies.bind(this),\n addDependencies: this.addJobDependencies.bind(this),\n };\n }\n\n /**\n * List all workflows\n */\n async list(params?: ListWorkflowsParams): Promise<WorkflowResponse[]> {\n return this.http.get<WorkflowResponse[]>(\"/workflows\", {\n params: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * Create a new workflow\n */\n async create(params: CreateWorkflowParams): Promise<CreateWorkflowResponse> {\n return this.http.post<CreateWorkflowResponse>(\"/workflows\", params);\n }\n\n /**\n * Get a workflow by ID\n */\n async get(id: string): Promise<WorkflowResponse> {\n const raw = await this.http.get<WorkflowGetPayload>(`/workflows/${id}`);\n return mapWorkflowGetResponse(raw);\n }\n\n /**\n * Cancel a workflow\n */\n async cancel(id: string): Promise<WorkflowResponse> {\n return this.http.post<WorkflowResponse>(`/workflows/${id}/cancel`);\n }\n\n /**\n * Retry a failed workflow\n *\n * Resets all failed/deadletter jobs back to pending and resumes the workflow.\n * Only workflows with status 'failed' can be retried.\n */\n async retry(id: string): Promise<WorkflowResponse> {\n return this.http.post<WorkflowResponse>(`/workflows/${id}/retry`);\n }\n\n // Workflow job operations (private implementations)\n //\n // The backend has no /workflows/{id}/jobs routes. Job rows and dependency\n // edges are on GET /workflows/{id} (WorkflowDetailResponse).\n\n private async listWorkflowJobs(workflowId: string): Promise<WorkflowJob[]> {\n const detail = await this.http.get<WorkflowDetailPayload>(\n `/workflows/${workflowId}`,\n );\n return mapWorkflowDetailJobs(detail);\n }\n\n private async getWorkflowJob(\n workflowId: string,\n jobId: string,\n ): Promise<WorkflowJob> {\n const jobs = await this.listWorkflowJobs(workflowId);\n const job = jobs.find((item) => item.id === jobId);\n if (!job) {\n throw new NotFoundError(\n `Job ${jobId} not found in workflow ${workflowId}`,\n );\n }\n return job;\n }\n\n private async getWorkflowJobsStatus(\n workflowId: string,\n ): Promise<WorkflowJobStatus[]> {\n const jobs = await this.listWorkflowJobs(workflowId);\n return jobs.map((job) => ({\n jobId: job.id,\n ...(job.key !== undefined && { key: job.key }),\n status: job.status,\n }));\n }\n\n private async getJobDependencies(\n jobId: string,\n ): Promise<JobWithDependencies> {\n return this.http.get<JobWithDependencies>(`/jobs/${jobId}/dependencies`);\n }\n\n private async addJobDependencies(\n jobId: string,\n params: AddDependenciesParams,\n ): Promise<AddDependenciesResponse> {\n const dependsOn = params.dependsOn ?? params.dependsOnJobIds ?? [];\n const mode =\n params.dependencyMode ??\n (params.dependencyType === \"any\" || params.dependencyType === \"all\"\n ? params.dependencyType\n : undefined);\n const raw = await this.http.post<{\n dependenciesAdded?: number;\n dependenciesMet?: boolean;\n }>(\n `/jobs/${jobId}/dependencies`,\n {\n depends_on: dependsOn,\n ...(mode ? { dependency_mode: mode } : {}),\n },\n { skipRequestConversion: true },\n );\n return {\n added: raw.dependenciesAdded ?? 0,\n dependenciesMet: raw.dependenciesMet ?? false,\n dependencies: [],\n };\n }\n}\n\ninterface WorkflowDetailPayload {\n id?: string;\n jobs?: Array<Record<string, unknown>>;\n dependencies?: Array<{\n parentJobId?: string;\n childJobId?: string;\n }>;\n}\n\n/** GET /workflows/{id} after camelCase conversion. */\nexport interface WorkflowGetPayload {\n id?: string;\n name?: string;\n status?: WorkflowResponse[\"status\"];\n createdAt?: string;\n completedAt?: string;\n totalJobs?: number;\n completedJobs?: number;\n failedJobs?: number;\n progressPercent?: number;\n progress?: {\n total?: number;\n completed?: number;\n failed?: number;\n };\n}\n\n/**\n * GET /workflows/{id} is WorkflowDetailResponse: counts live under\n * `progress`, not top-level total_jobs like list/cancel/retry.\n */\nexport function mapWorkflowGetResponse(\n raw: WorkflowGetPayload,\n): WorkflowResponse {\n const totalJobs = raw.totalJobs ?? raw.progress?.total ?? 0;\n const completedJobs = raw.completedJobs ?? raw.progress?.completed ?? 0;\n const failedJobs = raw.failedJobs ?? raw.progress?.failed ?? 0;\n const progressPercent =\n raw.progressPercent ??\n (totalJobs > 0 ? (completedJobs / totalJobs) * 100 : 0);\n return {\n id: String(raw.id ?? \"\"),\n name: String(raw.name ?? \"\"),\n status: raw.status ?? \"pending\",\n totalJobs,\n completedJobs,\n failedJobs,\n progressPercent,\n createdAt: String(raw.createdAt ?? \"\"),\n completedAt: raw.completedAt,\n };\n}\n\nfunction mapWorkflowDetailJobs(detail: WorkflowDetailPayload): WorkflowJob[] {\n const workflowId = String(detail.id ?? \"\");\n const deps = detail.dependencies ?? [];\n return (detail.jobs ?? []).map((job) => {\n const id = String(job.id ?? \"\");\n const timeoutMs =\n typeof job.timeoutMs === \"number\" ? job.timeoutMs : undefined;\n const errorObj = job.error;\n let error: string | undefined;\n if (typeof errorObj === \"string\") {\n error = errorObj;\n } else if (\n errorObj &&\n typeof errorObj === \"object\" &&\n \"message\" in errorObj\n ) {\n error = String((errorObj as { message: unknown }).message);\n }\n return {\n id,\n workflowId: String(job.workflowId ?? workflowId),\n // The API does not return the creation-time key (jobs store only a\n // workflow step), so there is nothing to put here unless a future\n // version sends one. Never fabricate \"\".\n ...(typeof job.key === \"string\" && job.key !== \"\" && { key: job.key }),\n queueName: String(job.queueName ?? job.queue ?? \"\"),\n status: job.status as WorkflowJob[\"status\"],\n payload: (job.payload as JsonObject) ?? {},\n result: (job.result as JsonObject | undefined) ?? undefined,\n error,\n dependsOn: deps\n .filter((dep) => dep.childJobId === id)\n .map((dep) => String(dep.parentJobId ?? \"\")),\n priority: Number(job.priority ?? 0),\n maxRetries: Number(job.maxRetries ?? 0),\n attempt: Number(job.attempt ?? 0),\n timeoutSeconds:\n timeoutMs != null\n ? Math.max(1, Math.floor(timeoutMs / 1000))\n : undefined,\n createdAt: String(job.createdAt ?? \"\"),\n startedAt: (job.startedAt as string | undefined) ?? undefined,\n completedAt: (job.completedAt as string | undefined) ?? undefined,\n };\n });\n}\n","/**\n * Webhooks Resource\n *\n * Handles outgoing webhook operations.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type {\n OutgoingWebhook,\n CreateOutgoingWebhookParams,\n UpdateOutgoingWebhookParams,\n TestWebhookResponse,\n OutgoingWebhookDelivery,\n} from \"../types/webhooks.js\";\n\nexport class WebhooksResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all outgoing webhooks\n */\n async list(): Promise<OutgoingWebhook[]> {\n return this.http.get<OutgoingWebhook[]>(\"/outgoing-webhooks\");\n }\n\n /**\n * Create a new outgoing webhook\n */\n async create(params: CreateOutgoingWebhookParams): Promise<OutgoingWebhook> {\n return this.http.post<OutgoingWebhook>(\"/outgoing-webhooks\", params);\n }\n\n /**\n * Get an outgoing webhook by ID\n */\n async get(id: string): Promise<OutgoingWebhook> {\n return this.http.get<OutgoingWebhook>(`/outgoing-webhooks/${id}`);\n }\n\n /**\n * Update an outgoing webhook\n */\n async update(\n id: string,\n params: UpdateOutgoingWebhookParams,\n ): Promise<OutgoingWebhook> {\n return this.http.put<OutgoingWebhook>(`/outgoing-webhooks/${id}`, params);\n }\n\n /**\n * Delete an outgoing webhook\n */\n async delete(id: string): Promise<void> {\n await this.http.delete(`/outgoing-webhooks/${id}`);\n }\n\n /**\n * Test an outgoing webhook\n */\n async test(id: string): Promise<TestWebhookResponse> {\n return this.http.post<TestWebhookResponse>(`/outgoing-webhooks/${id}/test`);\n }\n\n /**\n * Get webhook delivery history\n */\n async getDeliveries(id: string): Promise<OutgoingWebhookDelivery[]> {\n return this.http.get<OutgoingWebhookDelivery[]>(\n `/outgoing-webhooks/${id}/deliveries`,\n );\n }\n\n /**\n * Retry a specific webhook delivery\n */\n async retryDelivery(\n webhookId: string,\n deliveryId: string,\n ): Promise<{ success: boolean; message: string }> {\n return this.http.post<{ success: boolean; message: string }>(\n `/outgoing-webhooks/${webhookId}/retry/${deliveryId}`,\n );\n }\n}\n","/**\n * API Keys Resource\n *\n * Handles API key operations.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type {\n ApiKeySummary,\n CreateApiKeyParams,\n CreateApiKeyResponse,\n UpdateApiKeyParams,\n} from \"../types/api-keys.js\";\n\nexport class ApiKeysResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all API keys (without sensitive data)\n */\n async list(): Promise<ApiKeySummary[]> {\n return this.http.get<ApiKeySummary[]>(\"/api-keys\");\n }\n\n /**\n * Create a new API key\n */\n async create(params: CreateApiKeyParams): Promise<CreateApiKeyResponse> {\n return this.http.post<CreateApiKeyResponse>(\"/api-keys\", params);\n }\n\n /**\n * Get an API key by ID (without sensitive data)\n */\n async get(id: string): Promise<ApiKeySummary> {\n return this.http.get<ApiKeySummary>(`/api-keys/${id}`);\n }\n\n /**\n * Update an API key\n */\n async update(id: string, params: UpdateApiKeyParams): Promise<ApiKeySummary> {\n return this.http.put<ApiKeySummary>(`/api-keys/${id}`, params);\n }\n\n /**\n * Revoke an API key\n */\n async revoke(id: string): Promise<void> {\n await this.http.delete(`/api-keys/${id}`);\n }\n}\n","/**\n * Organizations Resource\n *\n * Handles organization operations including webhook token management.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport { UnsupportedOperationError } from \"../errors.js\";\nimport type {\n Organization,\n OrganizationSummary,\n CreateOrganizationParams,\n CreateOrganizationResponse,\n UpdateOrganizationParams,\n OrganizationUsage,\n OrganizationMember,\n CheckSlugResponse,\n WebhookTokenResponse,\n} from \"../types/organizations.js\";\n\nexport class OrganizationsResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Create a new organization (public endpoint, no auth required)\n */\n async create(\n params: CreateOrganizationParams,\n ): Promise<CreateOrganizationResponse> {\n return this.http.post<CreateOrganizationResponse>(\"/organizations\", params);\n }\n\n /**\n * List organizations\n */\n async list(): Promise<OrganizationSummary[]> {\n return this.http.get<OrganizationSummary[]>(\"/organizations\");\n }\n\n /**\n * Get an organization by ID\n */\n async get(id: string): Promise<Organization> {\n return this.http.get<Organization>(`/organizations/${id}`);\n }\n\n /**\n * Update an organization\n */\n async update(\n id: string,\n params: UpdateOrganizationParams,\n ): Promise<Organization> {\n return this.http.put<Organization>(`/organizations/${id}`, params);\n }\n\n /**\n * Delete an organization\n */\n async delete(id: string): Promise<void> {\n await this.http.delete(`/organizations/${id}`);\n }\n\n /**\n * Get organization usage and limits\n */\n async getUsage(): Promise<OrganizationUsage> {\n return this.http.get<OrganizationUsage>(\"/organizations/usage\");\n }\n\n /**\n * Get organization members\n */\n async getMembers(id: string): Promise<OrganizationMember[]> {\n return this.http.get<OrganizationMember[]>(`/organizations/${id}/members`);\n }\n\n /**\n * Check slug availability\n */\n async checkSlug(slug: string): Promise<CheckSlugResponse> {\n return this.http.get<CheckSlugResponse>(\"/organizations/check-slug\", {\n params: { slug },\n });\n }\n\n /**\n * Generate a unique slug from an organization name\n */\n async generateSlug(name: string): Promise<{ slug: string }> {\n return this.http.post<{ slug: string }>(\"/organizations/generate-slug\", {\n name,\n });\n }\n\n /**\n * Get the webhook token for the current organization.\n *\n * This token is used to verify incoming webhook payloads from Spooled.\n * Use this token to validate webhook signatures.\n *\n * @example\n * ```typescript\n * const { webhookToken, webhookUrl } = await client.organizations.getWebhookToken();\n * console.log('Webhook token:', webhookToken);\n * ```\n */\n async getWebhookToken(): Promise<WebhookTokenResponse> {\n return this.http.get<WebhookTokenResponse>(\"/organizations/webhook-token\");\n }\n\n /**\n * Regenerate the webhook token for the current organization.\n *\n * This invalidates the old token immediately. All webhook signature\n * verification using the old token will fail after regeneration.\n *\n * @example\n * ```typescript\n * const { webhookToken: newToken } = await client.organizations.regenerateWebhookToken();\n * console.log('New webhook token:', newToken);\n * ```\n */\n async regenerateWebhookToken(): Promise<WebhookTokenResponse> {\n return this.http.post<WebhookTokenResponse>(\n \"/organizations/webhook-token/regenerate\",\n );\n }\n\n /**\n * Clear/delete the webhook token for the current organization.\n *\n * @deprecated The API refuses this operation on purpose (an org without a\n * webhook token would have an open public ingestion endpoint) and always\n * answers with an error. This method now throws\n * {@link UnsupportedOperationError} without a network call; rotate the token\n * with {@link OrganizationsResource.regenerateWebhookToken} instead. It will\n * be removed in the next major release.\n */\n async clearWebhookToken(): Promise<void> {\n throw new UnsupportedOperationError(\n \"organizations.clearWebhookToken\",\n \"clearing the webhook token is not allowed; use organizations.regenerateWebhookToken() to rotate it\",\n );\n }\n}\n","/**\n * Billing Resource\n *\n * Stripe billing integration endpoints.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type {\n BillingStatus,\n CreateBillingPortalParams,\n CreateBillingPortalResponse,\n} from \"../types/billing.js\";\n\nexport class BillingResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Get billing status for the authenticated organization.\n *\n * GET /api/v1/billing/status\n */\n async getStatus(): Promise<BillingStatus> {\n return this.http.get<BillingStatus>(\"/billing/status\");\n }\n\n /**\n * Create a Stripe billing portal session.\n *\n * POST /api/v1/billing/portal\n */\n async createPortal(\n params: CreateBillingPortalParams,\n ): Promise<CreateBillingPortalResponse> {\n return this.http.post<CreateBillingPortalResponse>(\n \"/billing/portal\",\n params,\n );\n }\n}\n","/**\n * Dashboard Resource\n *\n * Provides aggregated dashboard data (used by the Spooled dashboard UI).\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type { DashboardData } from \"../types/dashboard.js\";\n\nexport class DashboardResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Get dashboard data for the current organization.\n *\n * GET /api/v1/dashboard\n */\n async get(): Promise<DashboardData> {\n return this.http.get<DashboardData>(\"/dashboard\");\n }\n}\n","/**\n * Health Resource\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type { HealthResponse } from \"../types/health.js\";\n\nexport class HealthResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Basic health check (public).\n *\n * GET /health\n */\n async get(): Promise<HealthResponse> {\n return this.http.get<HealthResponse>(\"/health\", { skipApiPrefix: true });\n }\n\n /**\n * Kubernetes liveness probe (public).\n *\n * GET /health/live\n */\n async liveness(): Promise<boolean> {\n try {\n await this.http.request<string>(\"/health/live\", {\n method: \"GET\",\n skipApiPrefix: true,\n skipRetry: true,\n });\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Kubernetes readiness probe (public).\n *\n * GET /health/ready\n */\n async readiness(): Promise<boolean> {\n try {\n await this.http.request<string>(\"/health/ready\", {\n method: \"GET\",\n skipApiPrefix: true,\n skipRetry: true,\n });\n return true;\n } catch {\n return false;\n }\n }\n}\n","/**\n * Metrics Resource\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\n\nexport class MetricsResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Prometheus metrics (public; may be protected by METRICS_TOKEN on the server).\n *\n * GET /metrics\n */\n async get(): Promise<string> {\n return this.http.get<string>(\"/metrics\", {\n skipApiPrefix: true,\n // Ensure we get the raw text response.\n headers: { Accept: \"text/plain\" },\n });\n }\n}\n","/**\n * Admin Resource\n *\n * Platform administration endpoints.\n * All endpoints require `X-Admin-Key` header.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type {\n AdminListOrganizationsParams,\n AdminOrganizationList,\n AdminOrganizationDetail,\n AdminUpdateOrganizationParams,\n AdminCreateOrganizationParams,\n AdminCreateOrganizationResponse,\n AdminCreateApiKeyParams,\n AdminApiKeyResponse,\n AdminDeleteOrganizationParams,\n AdminPlatformStats,\n AdminPlanLimits,\n} from \"../types/admin.js\";\nimport type { Organization } from \"../types/organizations.js\";\nimport { AuthenticationError } from \"../errors.js\";\n\nexport class AdminResource {\n constructor(\n private readonly http: HttpClient,\n private readonly adminKey: string | undefined,\n ) {}\n\n private headers(): Record<string, string> {\n if (!this.adminKey) {\n throw new AuthenticationError(\n \"Admin key is required for admin endpoints. Provide `adminKey` in SpooledClient config.\",\n );\n }\n return { \"X-Admin-Key\": this.adminKey };\n }\n\n /** GET /api/v1/admin/organizations */\n async listOrganizations(\n params?: AdminListOrganizationsParams,\n ): Promise<AdminOrganizationList> {\n const qp:\n | Record<string, string | number | boolean | undefined>\n | undefined = params\n ? {\n planTier: params.planTier,\n search: params.search,\n limit: params.limit,\n offset: params.offset,\n sortBy: params.sortBy,\n sortOrder: params.sortOrder,\n }\n : undefined;\n return this.http.get<AdminOrganizationList>(\"/admin/organizations\", {\n params: qp,\n headers: this.headers(),\n });\n }\n\n /** POST /api/v1/admin/organizations */\n async createOrganization(\n params: AdminCreateOrganizationParams,\n ): Promise<AdminCreateOrganizationResponse> {\n return this.http.post<AdminCreateOrganizationResponse>(\n \"/admin/organizations\",\n params,\n {\n headers: this.headers(),\n },\n );\n }\n\n /** GET /api/v1/admin/organizations/{id} */\n async getOrganization(id: string): Promise<AdminOrganizationDetail> {\n return this.http.get<AdminOrganizationDetail>(\n `/admin/organizations/${id}`,\n {\n headers: this.headers(),\n },\n );\n }\n\n /** PATCH /api/v1/admin/organizations/{id} */\n async updateOrganization(\n id: string,\n params: AdminUpdateOrganizationParams,\n ): Promise<Organization> {\n return this.http.patch<Organization>(`/admin/organizations/${id}`, params, {\n headers: this.headers(),\n });\n }\n\n /** DELETE /api/v1/admin/organizations/{id}?hard_delete=true */\n async deleteOrganization(\n id: string,\n params?: AdminDeleteOrganizationParams,\n ): Promise<void> {\n const qp:\n | Record<string, string | number | boolean | undefined>\n | undefined = params ? { hardDelete: params.hardDelete } : undefined;\n await this.http.delete(`/admin/organizations/${id}`, {\n headers: this.headers(),\n params: qp,\n });\n }\n\n /** POST /api/v1/admin/organizations/{id}/api-keys */\n async createApiKey(\n orgId: string,\n params: AdminCreateApiKeyParams,\n ): Promise<AdminApiKeyResponse> {\n return this.http.post<AdminApiKeyResponse>(\n `/admin/organizations/${orgId}/api-keys`,\n params,\n {\n headers: this.headers(),\n },\n );\n }\n\n /** POST /api/v1/admin/organizations/{id}/reset-usage */\n async resetUsage(orgId: string): Promise<void> {\n await this.http.post<void>(\n `/admin/organizations/${orgId}/reset-usage`,\n undefined,\n {\n headers: this.headers(),\n },\n );\n }\n\n /** GET /api/v1/admin/stats */\n async getStats(): Promise<AdminPlatformStats> {\n return this.http.get<AdminPlatformStats>(\"/admin/stats\", {\n headers: this.headers(),\n });\n }\n\n /** GET /api/v1/admin/plans */\n async listPlans(): Promise<AdminPlanLimits[]> {\n return this.http.get<AdminPlanLimits[]>(\"/admin/plans\", {\n headers: this.headers(),\n });\n }\n}\n","/**\n * Webhook Ingestion Resource\n *\n * The Spooled API ingests webhooks on one route:\n * `POST /api/v1/webhooks/{org_id}/custom`, authenticated by the org's webhook\n * token. The GitHub and Stripe routes were removed from the API.\n */\n\nimport type { HttpClient } from \"../utils/http.js\";\nimport type {\n InboundWebhookDelivery,\n IngestCustomWebhookParams,\n IngestCustomWebhookResponse,\n IngestGitHubWebhookOptions,\n IngestStripeWebhookOptions,\n ListInboundDeliveriesParams,\n} from \"../types/webhook-ingestion.js\";\nimport { UnsupportedOperationError } from \"../errors.js\";\nimport { toQueryTimestamp } from \"../utils/paging.js\";\n\nexport class WebhookIngestionResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Ingest a GitHub webhook.\n *\n * @deprecated The API has no `/webhooks/{org_id}/github` route (it always\n * answered 404). This method now throws {@link UnsupportedOperationError}\n * without a network call; point the GitHub webhook at `ingest.custom` /\n * `POST /api/v1/webhooks/{org_id}/custom` instead. It will be removed in the\n * next major release.\n */\n async github(\n _orgId: string,\n _body: string | Uint8Array | ArrayBuffer,\n _options: IngestGitHubWebhookOptions,\n ): Promise<void> {\n throw new UnsupportedOperationError(\n \"ingest.github\",\n \"the API has no GitHub webhook route; use ingest.custom (POST /webhooks/{org_id}/custom)\",\n );\n }\n\n /**\n * Ingest a Stripe webhook.\n *\n * @deprecated The API has no `/webhooks/{org_id}/stripe` route (it always\n * answered 404). This method now throws {@link UnsupportedOperationError}\n * without a network call; point the Stripe webhook at `ingest.custom` /\n * `POST /api/v1/webhooks/{org_id}/custom` instead. It will be removed in the\n * next major release.\n */\n async stripe(\n _orgId: string,\n _body: string | Uint8Array | ArrayBuffer,\n _options: IngestStripeWebhookOptions = {},\n ): Promise<void> {\n throw new UnsupportedOperationError(\n \"ingest.stripe\",\n \"the API has no Stripe webhook route; use ingest.custom (POST /webhooks/{org_id}/custom)\",\n );\n }\n\n /**\n * Ingest a custom webhook.\n *\n * POST /api/v1/webhooks/{org_id}/custom returns `{ jobId, queueName, status }`.\n * An older empty 200 maps to an empty object rather than throwing.\n */\n async custom(\n orgId: string,\n params: IngestCustomWebhookParams,\n opts?: { webhookToken?: string; forwardedProto?: string },\n ): Promise<IngestCustomWebhookResponse> {\n const headers: Record<string, string> = {\n ...(opts?.webhookToken ? { \"X-Webhook-Token\": opts.webhookToken } : {}),\n ...(opts?.forwardedProto\n ? { \"X-Forwarded-Proto\": opts.forwardedProto }\n : {}),\n };\n\n const raw = await this.http.post<IngestCustomWebhookResponse | string>(\n `/webhooks/${orgId}/custom`,\n params,\n { headers },\n );\n if (!raw || typeof raw === \"string\") {\n return {};\n }\n return {\n jobId: raw.jobId,\n queueName: raw.queueName,\n status: raw.status,\n };\n }\n\n /**\n * The inbound webhook log: accepted requests to\n * `POST /webhooks/{org_id}/custom`, newest first\n * (`GET /webhooks/deliveries`, API 0.1.122+).\n *\n * Needs an API key without a queue restriction (a queue-scoped key gets a\n * 403 `AuthorizationError`). Entries carry no payload and no signature;\n * requests that were rejected are not logged. `limit` defaults to 50 (at\n * most 100); an invalid filter is a 400 `ValidationError`.\n */\n async listDeliveries(\n params?: ListInboundDeliveriesParams,\n ): Promise<InboundWebhookDelivery[]> {\n const rows = await this.http.get<InboundWebhookDelivery[]>(\n \"/webhooks/deliveries\",\n {\n params: {\n status: params?.status,\n since: toQueryTimestamp(params?.since),\n queueName: params?.queueName,\n limit: params?.limit,\n offset: params?.offset,\n },\n },\n );\n return rows ?? [];\n }\n}\n","/**\n * Backend → SDK realtime event-name mapping.\n *\n * The backend's `RealtimeEvent` enum is serialized with\n * `#[serde(tag = \"type\", content = \"data\")]`, so events arrive on the wire as\n * `{ \"type\": \"<PascalCaseVariant>\", \"data\": { ...snake_case fields } }`, e.g.\n * `{ \"type\": \"JobCompleted\", \"data\": { \"job_id\": \"…\", \"duration_ms\": 12 } }`.\n *\n * The SDK's public event API, however, uses dotted names (`job.completed`,\n * `queue.stats`, …). Without translation, `rt.on('job.completed', …)` never\n * fires because the transport dispatches under the raw wire name\n * (`JobCompleted`). This map bridges the two: every variant of the backend enum\n * maps to its dotted SDK name.\n */\nexport const BACKEND_EVENT_TYPE_MAP: Record<string, string> = {\n JobStatusChange: \"job.status_changed\",\n JobCreated: \"job.created\",\n JobCompleted: \"job.completed\",\n JobFailed: \"job.failed\",\n QueueStats: \"queue.stats\",\n WorkerHeartbeat: \"worker.heartbeat\",\n WorkerRegistered: \"worker.registered\",\n WorkerDeregistered: \"worker.deregistered\",\n SystemHealth: \"system.health\",\n Ping: \"ping\",\n Error: \"error\",\n};\n\n/**\n * Translate a wire event `type` to the SDK's dotted event name.\n *\n * Names that are already dotted (or otherwise unknown) pass through unchanged,\n * so this is safe to call on every inbound message and keeps working if the\n * backend ever starts sending pre-dotted names.\n */\nexport function mapEventType(type: string): string {\n return BACKEND_EVENT_TYPE_MAP[type] ?? type;\n}\n","/**\n * WebSocket Realtime Client\n *\n * Provides real-time event streaming over WebSocket.\n */\n\nimport type {\n RealtimeConnectionOptions,\n RealtimeEvent,\n RealtimeEventType,\n SubscriptionFilter,\n ConnectionState,\n WebSocketCommand,\n} from \"./types.js\";\nimport { convertResponse } from \"../utils/casing.js\";\nimport { parseApiJson } from \"../utils/json.js\";\nimport { mapEventType } from \"./event-map.js\";\n\n/** Event handler type - simplified for internal use */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EventHandler = (data: any) => void;\n\n/** Generic event handler */\ntype GenericEventHandler = (event: RealtimeEvent) => void;\n\n/**\n * WebSocket Realtime Client\n *\n * Connects to the Spooled API WebSocket endpoint and emits typed events.\n */\nexport class WebSocketRealtimeClient {\n private readonly options: Required<RealtimeConnectionOptions>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private ws: any = null;\n private state: ConnectionState = \"disconnected\";\n private reconnectAttempts = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n /**\n * Set when the server rejected our token on the upgrade (e.g. HTTP 401/403).\n * The next (re)connect uses it to force the token provider to mint a fresh\n * JWT instead of replaying the rejected one (which would loop forever).\n */\n private authFailure = false;\n private subscriptions: Map<string, SubscriptionFilter> = new Map();\n\n // Event handlers\n private eventHandlers: Map<RealtimeEventType, Set<EventHandler>> = new Map();\n private allEventsHandlers: Set<GenericEventHandler> = new Set();\n private stateChangeHandlers: Set<(state: ConnectionState) => void> =\n new Set();\n\n constructor(options: RealtimeConnectionOptions) {\n // All defaults are applied AFTER the spread. SpooledRealtime forwards each of\n // these options as possibly-`undefined`, and a pre-spread default is clobbered\n // by an explicit `undefined` — e.g. autoReconnect would resolve to undefined\n // (falsy), silently disabling reconnect despite the documented default `true`,\n // and debug would become undefined and throw when connect() calls it.\n this.options = {\n ...options,\n autoReconnect: options.autoReconnect ?? true,\n maxReconnectAttempts: options.maxReconnectAttempts ?? 10,\n reconnectDelay: options.reconnectDelay ?? 1000,\n maxReconnectDelay: options.maxReconnectDelay ?? 30000,\n // Always resolve to a provider so reconnects can mint a fresh JWT.\n // Falls back to the static token when no provider is supplied.\n tokenProvider: options.tokenProvider ?? (async () => options.token),\n debug: options.debug ?? (() => {}),\n };\n }\n\n /**\n * Get current connection state\n */\n getState(): ConnectionState {\n return this.state;\n }\n\n /**\n * Get WebSocket implementation (browser native or Node.js ws package)\n */\n private async getWebSocketImpl(): Promise<typeof WebSocket> {\n if (typeof WebSocket !== \"undefined\") {\n return WebSocket;\n }\n // Node.js environment - use ws package with dynamic import for ESM compatibility\n const wsModule = await import(\"ws\");\n return wsModule.default as unknown as typeof WebSocket;\n }\n\n /**\n * Connect to the WebSocket server\n */\n async connect(): Promise<void> {\n if (this.state === \"connected\" || this.state === \"connecting\") {\n return;\n }\n\n this.setState(\"connecting\");\n\n // Build WebSocket URL with a freshly-minted token\n let wsUrl: string;\n try {\n wsUrl = await this.buildWsUrl();\n } catch (error) {\n this.setState(\"disconnected\");\n throw new Error(`Failed to acquire realtime token: ${error}`);\n }\n // Redact the token query param so JWTs never land in logs.\n this.options.debug(`Connecting to ${redactToken(wsUrl)}`);\n\n // Get WebSocket implementation (async for ESM compatibility in Node.js)\n let WebSocketImpl: typeof WebSocket;\n try {\n WebSocketImpl = await this.getWebSocketImpl();\n } catch (error) {\n this.setState(\"disconnected\");\n throw new Error(`Failed to load WebSocket implementation: ${error}`);\n }\n\n return new Promise((resolve, reject) => {\n try {\n this.ws = new WebSocketImpl(wsUrl);\n\n this.ws.onopen = () => {\n this.options.debug(\"WebSocket connected\");\n this.setState(\"connected\");\n this.reconnectAttempts = 0;\n this.resubscribeAll();\n resolve();\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.ws.onmessage = (event: any) => {\n this.handleMessage(\n typeof event.data === \"string\" ? event.data : String(event.data),\n );\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.ws.onclose = (event: any) => {\n this.options.debug(`WebSocket closed: ${event.code} ${event.reason}`);\n const wasConnecting = this.state === \"connecting\";\n this.handleDisconnect();\n if (wasConnecting) {\n reject(\n new Error(\n `WebSocket connection failed: ${event.reason || \"Unknown error\"}`,\n ),\n );\n }\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.ws.onerror = (event: any) => {\n this.options.debug(\"WebSocket error\", event);\n // The Node `ws` package surfaces a rejected upgrade here as an error\n // whose message is e.g. \"Unexpected server response: 401\". Flag it so\n // the next reconnect forces a fresh token rather than replaying the\n // rejected one. (Browsers don't expose the status; expiry-based\n // refresh still covers the common case there.)\n if (isAuthFailureEvent(event)) {\n this.authFailure = true;\n }\n };\n } catch (error) {\n this.setState(\"disconnected\");\n reject(error);\n }\n });\n }\n\n /**\n * Disconnect from the WebSocket server\n */\n disconnect(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n if (this.ws) {\n this.ws.onclose = null; // Prevent reconnect\n this.ws.close(1000, \"Client disconnect\");\n this.ws = null;\n }\n\n this.setState(\"disconnected\");\n this.subscriptions.clear();\n }\n\n /**\n * Subscribe to events matching a filter.\n *\n * The server applies filtering itself and sends no acknowledgement, so this\n * resolves as soon as the command has been written to the socket. The filter\n * is tracked locally so it is replayed automatically on reconnect.\n */\n async subscribe(filter: SubscriptionFilter): Promise<void> {\n const filterId = this.filterToId(filter);\n\n if (this.subscriptions.has(filterId)) {\n return; // Already subscribed\n }\n\n this.subscriptions.set(filterId, filter);\n\n if (this.state === \"connected\") {\n this.sendCommand(\"Subscribe\", filter);\n }\n }\n\n /**\n * Unsubscribe from events matching a filter.\n *\n * Fire-and-forget, like {@link subscribe} — the server sends no ack.\n */\n async unsubscribe(filter: SubscriptionFilter): Promise<void> {\n const filterId = this.filterToId(filter);\n\n if (!this.subscriptions.has(filterId)) {\n return; // Not subscribed\n }\n\n this.subscriptions.delete(filterId);\n\n if (this.state === \"connected\") {\n this.sendCommand(\"Unsubscribe\", filter);\n }\n }\n\n /**\n * Add an event listener for a specific event type\n */\n on<T extends RealtimeEventType>(type: T, handler: EventHandler): () => void {\n if (!this.eventHandlers.has(type)) {\n this.eventHandlers.set(type, new Set());\n }\n this.eventHandlers.get(type)!.add(handler);\n\n // Return unsubscribe function\n return () => this.off(type, handler);\n }\n\n /**\n * Remove an event listener\n */\n off<T extends RealtimeEventType>(type: T, handler: EventHandler): void {\n const handlers = this.eventHandlers.get(type);\n if (handlers) {\n handlers.delete(handler);\n }\n }\n\n /**\n * Add a listener for all events\n */\n onEvent(handler: GenericEventHandler): () => void {\n this.allEventsHandlers.add(handler);\n return () => this.allEventsHandlers.delete(handler);\n }\n\n /**\n * Add a listener for state changes\n */\n onStateChange(handler: (state: ConnectionState) => void): () => void {\n this.stateChangeHandlers.add(handler);\n return () => this.stateChangeHandlers.delete(handler);\n }\n\n // Private methods\n\n private async buildWsUrl(): Promise<string> {\n // wsUrl should already be ws:// or wss://\n const wsBase = this.options.wsUrl;\n // Reuse the provider's cached JWT unless the previous attempt was rejected\n // for auth (401/403 on the upgrade), in which case force a fresh token so a\n // stale/revoked one can't block recovery. Clear the flag either way.\n const forceRefresh = this.authFailure;\n this.authFailure = false;\n const token = await this.options.tokenProvider(forceRefresh);\n return `${wsBase}/api/v1/ws?token=${encodeURIComponent(token)}`;\n }\n\n private setState(state: ConnectionState): void {\n if (this.state !== state) {\n this.state = state;\n this.stateChangeHandlers.forEach((handler) => handler(state));\n }\n }\n\n private handleMessage(data: string): void {\n try {\n // Backend emits snake_case; convert to camelCase to match the typed\n // event shapes (jobId, queueName, durationMs, ...). User blobs like\n // `result`/`payload` are preserved via SKIP_CONVERSION_KEYS.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const message = convertResponse(parseApiJson(data)) as any;\n\n // The backend tags events with the PascalCase enum variant name\n // (`JobCompleted`, `QueueStats`, ...); the SDK's public API dispatches by\n // dotted name (`job.completed`, `queue.stats`). Translate before dispatch\n // so `on('job.completed', ...)` fires. Unknown/pre-dotted names pass\n // through unchanged.\n const eventType = mapEventType(String(message.type));\n message.type = eventType;\n const event = message as RealtimeEvent;\n this.options.debug(`Received event: ${eventType}`, event);\n\n // Emit to specific handlers\n const handlers = this.eventHandlers.get(eventType as RealtimeEventType);\n if (handlers) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const eventData = (event as any).data;\n handlers.forEach((handler) => {\n try {\n handler(eventData);\n } catch (error) {\n this.options.debug(\"Event handler error\", error);\n }\n });\n }\n\n // Emit to all-events handlers\n this.allEventsHandlers.forEach((handler) => {\n try {\n handler(event);\n } catch (error) {\n this.options.debug(\"Event handler error\", error);\n }\n });\n } catch (error) {\n this.options.debug(\"Failed to parse message\", { data, error });\n }\n }\n\n private handleDisconnect(): void {\n this.ws = null;\n\n if (\n this.options.autoReconnect &&\n this.reconnectAttempts < this.options.maxReconnectAttempts\n ) {\n this.scheduleReconnect();\n } else {\n this.setState(\"disconnected\");\n }\n }\n\n private scheduleReconnect(): void {\n this.setState(\"reconnecting\");\n this.reconnectAttempts++;\n\n const baseDelay = Math.min(\n this.options.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1),\n this.options.maxReconnectDelay,\n );\n // Add randomized jitter (up to +25%) to avoid a thundering-herd reconnect\n // storm when many clients drop at the same moment. Matches utils/retry.ts.\n const delay = Math.floor(baseDelay + Math.random() * baseDelay * 0.25);\n\n this.options.debug(\n `Scheduling reconnect attempt ${this.reconnectAttempts} in ${delay}ms`,\n );\n\n this.reconnectTimer = setTimeout(async () => {\n try {\n await this.connect();\n } catch (error) {\n this.options.debug(\"Reconnect failed\", error);\n if (\n this.options.autoReconnect &&\n this.reconnectAttempts < this.options.maxReconnectAttempts\n ) {\n this.scheduleReconnect();\n } else {\n this.setState(\"disconnected\");\n }\n }\n }, delay);\n }\n\n private resubscribeAll(): void {\n for (const filter of this.subscriptions.values()) {\n try {\n this.sendCommand(\"Subscribe\", filter);\n } catch (error) {\n this.options.debug(\"Failed to resubscribe\", { filter, error });\n }\n }\n }\n\n /**\n * Send a subscribe/unsubscribe command to the server.\n *\n * The backend `ClientCommand` shape is `{ cmd, queue, job_id }` and it sends\n * no acknowledgement, so this is fire-and-forget — it writes to the socket\n * and returns. The `SubscriptionFilter`'s `workerId`/`scheduleId` have no\n * server-side equivalent and are ignored.\n */\n private sendCommand(\n cmd: \"Subscribe\" | \"Unsubscribe\",\n filter: SubscriptionFilter,\n ): void {\n if (!this.ws || this.state !== \"connected\") {\n throw new Error(\"WebSocket not connected\");\n }\n\n const command: WebSocketCommand = {\n cmd,\n queue: filter.queueName,\n job_id: filter.jobId,\n };\n this.ws.send(JSON.stringify(command));\n }\n\n private filterToId(filter: SubscriptionFilter): string {\n return JSON.stringify(filter);\n }\n}\n\n/**\n * Redact sensitive auth query params (token/api_key) from a URL for logging.\n */\nexport function redactToken(url: string): string {\n return url.replace(/([?&](?:token|api_key)=)[^&]*/gi, \"$1***\");\n}\n\n/**\n * Detect whether a WebSocket error event represents an auth rejection on the\n * upgrade (HTTP 401/403). The Node `ws` package reports these as an error whose\n * message is like \"Unexpected server response: 401\"; different runtimes may put\n * the text on `message`, `error.message`, or `reason`.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isAuthFailureEvent(event: any): boolean {\n if (!event) {\n return false;\n }\n const status = event.status ?? event.statusCode ?? event.error?.status;\n if (status === 401 || status === 403) {\n return true;\n }\n const text = String(\n event.message ?? event.error?.message ?? event.reason ?? \"\",\n );\n return /\\b(401|403)\\b/.test(text);\n}\n","/**\n * SSE Realtime Client\n *\n * Provides real-time event streaming over Server-Sent Events.\n */\n\nimport type {\n RealtimeConnectionOptions,\n RealtimeEvent,\n RealtimeEventType,\n SubscriptionFilter,\n ConnectionState,\n} from \"./types.js\";\nimport { convertResponse } from \"../utils/casing.js\";\nimport { parseApiJson } from \"../utils/json.js\";\nimport { mapEventType } from \"./event-map.js\";\n\n/** Event handler type - simplified for internal use */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EventHandler = (data: any) => void;\n\n/** Generic event handler */\ntype GenericEventHandler = (event: RealtimeEvent) => void;\n\n/**\n * Every SSE `event:` name the API sends. The server always names its frames\n * (`event: job.completed`), and an EventSource delivers named frames only to\n * `addEventListener(name, ...)` — `onmessage` sees unnamed frames alone — so\n * without these listeners the client received nothing at all.\n */\nexport const SSE_EVENT_NAMES = [\n \"job.created\",\n \"job.status\",\n \"job.completed\",\n \"job.failed\",\n \"queue.stats\",\n \"worker.heartbeat\",\n \"worker.registered\",\n \"worker.deregistered\",\n \"system.health\",\n \"ping\",\n \"error\",\n] as const;\n\n/**\n * Job statuses after which the API closes a job stream\n * (`/events/jobs/{id}` ends once the job reaches one of these).\n */\nconst TERMINAL_JOB_STATUSES = new Set([\n \"completed\",\n \"failed\",\n \"deadletter\",\n \"cancelled\",\n]);\n\n/**\n * How long a connection must stay open before it counts as healthy and gives\n * the next reconnect a fresh attempt budget. A stream the server closes right\n * after opening is not healthy, however \"successfully\" it opened.\n */\nconst STABLE_CONNECTION_MS = 30_000;\n\n/**\n * SSE Realtime Client\n *\n * Connects to the Spooled API SSE endpoint and emits typed events.\n * SSE is unidirectional - subscriptions must be set at connection time.\n */\nexport class SseRealtimeClient {\n private readonly options: Required<RealtimeConnectionOptions>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private eventSource: any = null;\n private state: ConnectionState = \"disconnected\";\n private reconnectAttempts = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private filter: SubscriptionFilter | null = null;\n /** When the current connection opened (for the stable-connection check). */\n private connectedAt: number | null = null;\n /** The server finished this stream on purpose (terminal job); do not reconnect. */\n private streamEnded = false;\n /** The server rejected our token; mint a fresh one for the next connect. */\n private forceTokenRefresh = false;\n\n // Event handlers\n private eventHandlers: Map<RealtimeEventType, Set<EventHandler>> = new Map();\n private allEventsHandlers: Set<GenericEventHandler> = new Set();\n private stateChangeHandlers: Set<(state: ConnectionState) => void> =\n new Set();\n\n constructor(options: RealtimeConnectionOptions) {\n // Defaults applied AFTER the spread — a pre-spread default is clobbered by an\n // explicit `undefined` forwarded from SpooledRealtime (e.g. autoReconnect would\n // resolve to undefined/falsy, silently disabling reconnect despite the\n // documented default `true`).\n this.options = {\n ...options,\n autoReconnect: options.autoReconnect ?? true,\n maxReconnectAttempts: options.maxReconnectAttempts ?? 10,\n reconnectDelay: options.reconnectDelay ?? 1000,\n maxReconnectDelay: options.maxReconnectDelay ?? 30000,\n // Always resolve to a provider so reconnects can mint a fresh token.\n // Falls back to the static token when no provider is supplied.\n tokenProvider: options.tokenProvider ?? (async () => options.token),\n // Coalesce debug to a no-op AFTER the spread. A caller that omits debug\n // still passes `debug: undefined` explicitly (e.g. via SpooledRealtime),\n // and spreading that would overwrite a pre-spread default with undefined,\n // making connect() call `this.options.debug(...)` on undefined and throw\n // \"this.options.debug is not a function\". Guarding here keeps it callable\n // regardless of what the caller passes.\n debug: options.debug ?? (() => {}),\n };\n }\n\n /**\n * Get current connection state\n */\n getState(): ConnectionState {\n return this.state;\n }\n\n /**\n * Connect to the SSE server with a subscription filter\n */\n async connect(filter?: SubscriptionFilter): Promise<void> {\n if (this.state === \"connected\" || this.state === \"connecting\") {\n return;\n }\n\n this.filter = filter || null;\n this.streamEnded = false;\n\n this.setState(\"connecting\");\n\n const sseUrl = this.buildSseUrl(filter);\n // Logged before the credential is added. A platform EventSource puts the\n // token on the query string, and that must not land in debug output.\n this.options.debug(`Connecting to SSE: ${sseUrl}`);\n\n // The platform EventSource (browser, and Node's undici global) ignores a\n // `fetch` option, so an Authorization header passed that way is never\n // sent. The `eventsource` package is the one that honors `fetch`. Prefer\n // the package when there is no platform constructor.\n const usingPlatformEventSource = typeof EventSource !== \"undefined\";\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let EventSourceImpl: any;\n if (usingPlatformEventSource) {\n EventSourceImpl = EventSource;\n } else {\n // Dynamic import for ESM compatibility\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod = (await import(\"eventsource\")) as any;\n EventSourceImpl = mod.default || mod.EventSource || mod;\n } catch {\n this.setState(\"disconnected\");\n throw new Error(\n \"eventsource package is required for SSE in Node.js. Install it with: npm install eventsource\",\n );\n }\n }\n\n // Ask the provider on every (re)connect so a stale token never blocks\n // recovery. It caches the JWT itself, so only force a new login after the\n // server actually rejected the token (a 401/403), not on every retry.\n let token: string;\n try {\n const force = this.forceTokenRefresh;\n this.forceTokenRefresh = false;\n token = await this.options.tokenProvider(force);\n } catch (error) {\n this.setState(\"disconnected\");\n throw new Error(`Failed to acquire realtime token: ${error}`);\n }\n\n return new Promise((resolve, reject) => {\n try {\n // Platform EventSource cannot set a header. The API accepts `?token=`\n // for that case (the same credential the WebSocket client sends). The\n // `eventsource` package can set Authorization, so it keeps the header\n // and the token stays off the URL.\n const connectUrl = usingPlatformEventSource\n ? appendSseToken(sseUrl, token)\n : sseUrl;\n this.eventSource = new EventSourceImpl(\n connectUrl,\n usingPlatformEventSource\n ? undefined\n : {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n fetch: (input: any, init: any) =>\n fetch(input, {\n ...init,\n headers: {\n ...init?.headers,\n Authorization: `Bearer ${token}`,\n },\n }),\n },\n );\n\n this.eventSource.onopen = () => {\n this.options.debug(\"SSE connected\");\n this.setState(\"connected\");\n // The attempt counter is NOT reset here: an open that the server\n // closes at once (a finished job's stream) would otherwise refill the\n // budget on every cycle and reconnect forever. It resets once the\n // connection has proved stable (see handleDisconnect).\n this.connectedAt = Date.now();\n resolve();\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.eventSource.onmessage = (event: any) => {\n this.handleMessage(event.data);\n };\n for (const name of SSE_EVENT_NAMES) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.eventSource.addEventListener(name, (event: any) => {\n // \"error\" also fires for connection failures, which carry no data\n // and are handled by onerror below.\n if (typeof event?.data === \"string\") this.handleMessage(event.data);\n });\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.eventSource.onerror = (event: any) => {\n this.options.debug(\"SSE error\");\n\n // The `eventsource` package reports the HTTP status of a rejected\n // connection as `code`.\n if (event?.code === 401 || event?.code === 403) {\n this.forceTokenRefresh = true;\n }\n\n if (this.state === \"connecting\") {\n this.setState(\"disconnected\");\n // Close the abandoned EventSource so it doesn't keep auto-reconnecting\n // in the background after we reject the initial connect promise.\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n reject(new Error(\"SSE connection failed\"));\n return;\n }\n\n this.handleDisconnect();\n };\n } catch (error) {\n this.setState(\"disconnected\");\n reject(error);\n }\n });\n }\n\n /**\n * Disconnect from the SSE server\n */\n disconnect(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n\n this.setState(\"disconnected\");\n this.filter = null;\n this.connectedAt = null;\n this.streamEnded = false;\n }\n\n /**\n * Reconnect with a new filter (SSE requires reconnection to change subscriptions)\n */\n async reconnect(filter?: SubscriptionFilter): Promise<void> {\n this.disconnect();\n await this.connect(filter);\n }\n\n /**\n * Add an event listener for a specific event type\n */\n on<T extends RealtimeEventType>(type: T, handler: EventHandler): () => void {\n if (!this.eventHandlers.has(type)) {\n this.eventHandlers.set(type, new Set());\n }\n this.eventHandlers.get(type)!.add(handler);\n\n return () => this.off(type, handler);\n }\n\n /**\n * Remove an event listener\n */\n off<T extends RealtimeEventType>(type: T, handler: EventHandler): void {\n const handlers = this.eventHandlers.get(type);\n if (handlers) {\n handlers.delete(handler);\n }\n }\n\n /**\n * Add a listener for all events\n */\n onEvent(handler: GenericEventHandler): () => void {\n this.allEventsHandlers.add(handler);\n return () => this.allEventsHandlers.delete(handler);\n }\n\n /**\n * Add a listener for state changes\n */\n onStateChange(handler: (state: ConnectionState) => void): () => void {\n this.stateChangeHandlers.add(handler);\n return () => this.stateChangeHandlers.delete(handler);\n }\n\n // Private methods\n\n private buildSseUrl(filter?: SubscriptionFilter): string {\n // Backend SSE endpoints:\n // - GET /api/v1/events (every org event; ?queue= narrows it to one queue)\n // - GET /api/v1/events/jobs/{id} (single job status stream)\n // - GET /api/v1/events/queues/{name} (queue.stats counters only)\n //\n // A queue subscription uses /events?queue=: the per-queue route carries only\n // queue.stats, so `on('job.created')` after `subscribe({ queueName })` would\n // never fire there. Requires API 0.1.114+.\n if (filter?.jobId) {\n return `${this.options.baseUrl}/api/v1/events/jobs/${encodeURIComponent(filter.jobId)}`;\n }\n if (filter?.queueName) {\n return `${this.options.baseUrl}/api/v1/events?queue=${encodeURIComponent(filter.queueName)}`;\n }\n return `${this.options.baseUrl}/api/v1/events`;\n }\n\n private setState(state: ConnectionState): void {\n if (this.state !== state) {\n this.state = state;\n this.stateChangeHandlers.forEach((handler) => handler(state));\n }\n }\n\n private handleMessage(data: string): void {\n try {\n // Backend emits snake_case; convert to camelCase to match the typed\n // event shapes. User blobs (`result`/`payload`) are preserved via\n // SKIP_CONVERSION_KEYS.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const parsed = convertResponse(parseApiJson(data)) as any;\n // Translate the backend's PascalCase variant name (`JobCompleted`) to the\n // SDK's dotted event name (`job.completed`) before dispatch, matching the\n // WebSocket client. Unknown/pre-dotted names pass through unchanged.\n const eventType = mapEventType(String(parsed.type));\n parsed.type = eventType;\n const event = parsed as RealtimeEvent;\n this.options.debug(`Received SSE event: ${eventType}`, event);\n\n // A job stream ends once the job is terminal; remember it so the close\n // that follows is not treated as a dropped connection.\n if (this.filter?.jobId && isStreamEndingEvent(eventType, parsed.data)) {\n this.streamEnded = true;\n }\n\n // Emit to specific handlers\n const handlers = this.eventHandlers.get(eventType as RealtimeEventType);\n if (handlers) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const eventData = (event as any).data;\n handlers.forEach((handler) => {\n try {\n handler(eventData);\n } catch (error) {\n this.options.debug(\"Event handler error\", error);\n }\n });\n }\n\n // Emit to all-events handlers\n this.allEventsHandlers.forEach((handler) => {\n try {\n handler(event);\n } catch (error) {\n this.options.debug(\"Event handler error\", error);\n }\n });\n } catch (error) {\n this.options.debug(\"Failed to parse SSE message\", { data, error });\n }\n }\n\n private handleDisconnect(): void {\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n\n // The server ended this stream deliberately (a terminal job): reconnecting\n // would only replay the terminal event again and again.\n if (this.streamEnded) {\n this.connectedAt = null;\n this.setState(\"disconnected\");\n return;\n }\n\n // A connection that stayed up long enough was healthy (e.g. the server's\n // 30 minute cap closed it): give the reconnect a fresh budget. One that\n // closed right after opening keeps counting toward maxReconnectAttempts.\n if (\n this.connectedAt !== null &&\n Date.now() - this.connectedAt >= STABLE_CONNECTION_MS\n ) {\n this.reconnectAttempts = 0;\n }\n this.connectedAt = null;\n\n if (\n this.options.autoReconnect &&\n this.reconnectAttempts < this.options.maxReconnectAttempts\n ) {\n this.scheduleReconnect();\n } else {\n this.setState(\"disconnected\");\n }\n }\n\n private scheduleReconnect(): void {\n this.setState(\"reconnecting\");\n this.reconnectAttempts++;\n\n const baseDelay = Math.min(\n this.options.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1),\n this.options.maxReconnectDelay,\n );\n // Add randomized jitter (up to +25%) to avoid synchronized reconnect\n // storms across clients. Matches utils/retry.ts.\n const delay = Math.floor(baseDelay + Math.random() * baseDelay * 0.25);\n\n this.options.debug(\n `Scheduling SSE reconnect attempt ${this.reconnectAttempts} in ${delay}ms`,\n );\n\n this.reconnectTimer = setTimeout(async () => {\n try {\n await this.connect(this.filter || undefined);\n } catch (error) {\n this.options.debug(\"SSE reconnect failed\", error);\n if (\n this.options.autoReconnect &&\n this.reconnectAttempts < this.options.maxReconnectAttempts\n ) {\n this.scheduleReconnect();\n } else {\n this.setState(\"disconnected\");\n }\n }\n }, delay);\n }\n}\n\n/**\n * Credential for a platform EventSource, which cannot send Authorization.\n * Appended after the subscription query (`?queue=`), so the separator depends\n * on whether the URL already has a query string.\n */\nfunction appendSseToken(url: string, token: string): string {\n const separator = url.includes(\"?\") ? \"&\" : \"?\";\n return `${url}${separator}token=${encodeURIComponent(token)}`;\n}\n\n/**\n * Whether an inbound event means the API is about to close this job stream:\n * the job reached a terminal status, or the server sent its own `error` (e.g.\n * \"Job not found\"), which it follows by closing the stream.\n */\nfunction isStreamEndingEvent(eventType: string, data: unknown): boolean {\n if (eventType === \"error\" || eventType === \"job.completed\") {\n return true;\n }\n const record = (data ?? {}) as { newStatus?: unknown; willRetry?: unknown };\n if (eventType === \"job.failed\") {\n return record.willRetry === false;\n }\n if (eventType === \"job.status_changed\" || eventType === \"job.status\") {\n return (\n typeof record.newStatus === \"string\" &&\n TERMINAL_JOB_STATUSES.has(record.newStatus)\n );\n }\n return false;\n}\n","/**\n * Realtime Module\n *\n * Provides WebSocket and SSE clients for real-time event streaming.\n */\n\nexport * from \"./types.js\";\nexport { WebSocketRealtimeClient } from \"./websocket.js\";\nexport { SseRealtimeClient } from \"./sse.js\";\n\nimport { WebSocketRealtimeClient } from \"./websocket.js\";\nimport { SseRealtimeClient } from \"./sse.js\";\nimport type {\n RealtimeConnectionOptions,\n RealtimeEvent,\n RealtimeEventType,\n SubscriptionFilter,\n ConnectionState,\n} from \"./types.js\";\n\n/** Options for creating a SpooledRealtime instance */\nexport interface SpooledRealtimeOptions {\n /**\n * Connection type: 'websocket' or 'sse' (default: 'websocket').\n *\n * Default is WebSocket because it’s typically the lowest server load:\n * - WebSocket uses push/pubsub in the backend\n * - SSE job/queue endpoints poll the database periodically\n */\n type?: \"websocket\" | \"sse\";\n /** Auto-reconnect on disconnect (default: true) */\n autoReconnect?: boolean;\n /** Maximum reconnect attempts (default: 10) */\n maxReconnectAttempts?: number;\n /** Initial reconnect delay in ms (default: 1000) */\n reconnectDelay?: number;\n /** Maximum reconnect delay in ms (default: 30000) */\n maxReconnectDelay?: number;\n}\n\n/** Full options including internal fields */\ninterface FullRealtimeOptions extends SpooledRealtimeOptions {\n baseUrl: string;\n wsUrl: string;\n token: string;\n /** Async provider that supplies a valid JWT for each (re)connect */\n tokenProvider?: (forceRefresh?: boolean) => Promise<string>;\n debug?: (message: string, meta?: unknown) => void;\n}\n\n/** Event handler type - simplified for internal use */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EventHandler = (data: any) => void;\n\n/** Generic event handler */\ntype GenericEventHandler = (event: RealtimeEvent) => void;\n\n/**\n * Unified Realtime Client\n *\n * Wraps WebSocket and SSE clients with a common interface.\n */\nexport class SpooledRealtime {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private readonly client: any;\n\n constructor(options: FullRealtimeOptions) {\n const connectionOptions: RealtimeConnectionOptions = {\n baseUrl: options.baseUrl,\n wsUrl: options.wsUrl,\n token: options.token,\n tokenProvider: options.tokenProvider,\n autoReconnect: options.autoReconnect,\n maxReconnectAttempts: options.maxReconnectAttempts,\n reconnectDelay: options.reconnectDelay,\n maxReconnectDelay: options.maxReconnectDelay,\n debug: options.debug,\n };\n\n if (options.type === \"sse\") {\n this.client = new SseRealtimeClient(connectionOptions);\n } else {\n this.client = new WebSocketRealtimeClient(connectionOptions);\n }\n }\n\n /**\n * Get current connection state\n */\n getState(): ConnectionState {\n return this.client.getState();\n }\n\n /**\n * Connect to the realtime server\n */\n async connect(): Promise<void> {\n return this.client.connect();\n }\n\n /**\n * Disconnect from the realtime server\n */\n disconnect(): void {\n this.client.disconnect();\n }\n\n /**\n * Subscribe to events matching a filter\n *\n * @example\n * ```typescript\n * // Subscribe to all events from a queue\n * await realtime.subscribe({ queueName: 'my-queue' });\n *\n * // Subscribe to events for a specific job\n * await realtime.subscribe({ jobId: 'job-123' });\n * ```\n */\n async subscribe(filter: SubscriptionFilter): Promise<void> {\n // SSE subscriptions are effectively endpoint-based; change requires reconnect.\n if (typeof this.client.subscribe === \"function\") {\n return this.client.subscribe(filter);\n }\n return this.client.reconnect(filter);\n }\n\n /**\n * Unsubscribe from events matching a filter\n */\n async unsubscribe(filter: SubscriptionFilter): Promise<void> {\n if (typeof this.client.unsubscribe === \"function\") {\n return this.client.unsubscribe(filter);\n }\n // For SSE, unsubscribing means disconnecting if the filter matches current connection.\n this.client.disconnect();\n }\n\n /**\n * Add an event listener for a specific event type\n *\n * @example\n * ```typescript\n * realtime.on('job.completed', (data) => {\n * console.log('Job completed:', data.jobId);\n * });\n *\n * realtime.on('job.failed', (data) => {\n * console.error('Job failed:', data.error);\n * });\n * ```\n */\n on<T extends RealtimeEventType>(type: T, handler: EventHandler): () => void {\n return this.client.on(type, handler);\n }\n\n /**\n * Remove an event listener\n */\n off<T extends RealtimeEventType>(type: T, handler: EventHandler): void {\n this.client.off(type, handler);\n }\n\n /**\n * Add a listener for all events\n *\n * @example\n * ```typescript\n * realtime.onEvent((event) => {\n * console.log(`Event: ${event.type}`, event.data);\n * });\n * ```\n */\n onEvent(handler: GenericEventHandler): () => void {\n return this.client.onEvent(handler);\n }\n\n /**\n * Add a listener for connection state changes\n *\n * @example\n * ```typescript\n * realtime.onStateChange((state) => {\n * console.log('Connection state:', state);\n * });\n * ```\n */\n onStateChange(handler: (state: ConnectionState) => void): () => void {\n return this.client.onStateChange(handler);\n }\n}\n","/**\n * Proto Loader Utility\n *\n * Dynamically loads the Spooled proto file for gRPC communication.\n */\n\n/* global __dirname */\n\nimport * as grpc from \"@grpc/grpc-js\";\nimport * as protoLoader from \"@grpc/proto-loader\";\nimport { existsSync } from \"fs\";\nimport { fileURLToPath } from \"url\";\nimport { dirname, join } from \"path\";\nimport type { ServiceClientConstructor } from \"@grpc/grpc-js\";\n\n/** Proto loader options for consistent parsing */\nexport const PROTO_LOADER_OPTIONS: protoLoader.Options = {\n keepCase: false, // Convert snake_case to camelCase\n longs: String, // Represent int64 as strings\n enums: String, // Represent enums as strings\n defaults: true, // Include default values\n oneofs: true, // Support oneofs\n};\n\nexport interface SpooledProtoDefinition {\n spooled: {\n v1: {\n QueueService: ServiceClientConstructor;\n WorkerService: ServiceClientConstructor;\n };\n };\n}\n\nlet cachedDefinition: SpooledProtoDefinition | null = null;\n\n/**\n * Resolve the directory that contains this module (ESM or CJS).\n */\nfunction getModuleDir(): string {\n if (typeof import.meta?.url !== \"undefined\") {\n return dirname(fileURLToPath(import.meta.url));\n }\n return __dirname;\n}\n\n/**\n * Get the path to the proto file.\n *\n * tsup bundles `src/grpc/loader.ts` into `dist/index.js`, so a single\n * `../../proto` relative path (correct from `src/grpc/`) resolves one level\n * above the package root from `dist/` and breaks gRPC client construction.\n * Try both layouts (plus package-root fallbacks) and pick the first hit.\n */\nexport function getProtoPath(): string {\n const moduleDir = getModuleDir();\n const candidates = [\n // Bundled ESM/CJS: dist/index.js → ../proto/spooled.proto\n join(moduleDir, \"../proto/spooled.proto\"),\n // Source / unbundled: src/grpc/loader.ts → ../../proto/spooled.proto\n join(moduleDir, \"../../proto/spooled.proto\"),\n // Extra safety if moduleDir is package root\n join(moduleDir, \"proto/spooled.proto\"),\n ];\n\n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n\n throw new Error(\n `Spooled gRPC proto not found. Tried: ${candidates.join(\", \")}. ` +\n `Ensure the package's proto/spooled.proto is installed next to dist/.`,\n );\n}\n\n/**\n * Load the Spooled proto definition synchronously.\n * Caches the result for subsequent calls.\n */\nexport function loadProtoDefinition(): SpooledProtoDefinition {\n if (cachedDefinition) {\n return cachedDefinition;\n }\n\n const protoPath = getProtoPath();\n\n const packageDefinition = protoLoader.loadSync(\n protoPath,\n PROTO_LOADER_OPTIONS,\n );\n const grpcObject = grpc.loadPackageDefinition(packageDefinition);\n\n cachedDefinition = grpcObject as unknown as SpooledProtoDefinition;\n return cachedDefinition;\n}\n\n/**\n * Load the Spooled proto definition asynchronously.\n */\nexport async function loadProtoDefinitionAsync(): Promise<SpooledProtoDefinition> {\n if (cachedDefinition) {\n return cachedDefinition;\n }\n\n const protoPath = getProtoPath();\n\n const packageDefinition = await protoLoader.load(\n protoPath,\n PROTO_LOADER_OPTIONS,\n );\n const grpcObject = grpc.loadPackageDefinition(packageDefinition);\n\n cachedDefinition = grpcObject as unknown as SpooledProtoDefinition;\n return cachedDefinition;\n}\n\n/**\n * Clear the cached proto definition (mainly for testing).\n */\nexport function clearProtoCache(): void {\n cachedDefinition = null;\n}\n","/**\n * gRPC message encoding and decoding shared by the unary client and the\n * StreamJobs / ProcessJobs streams.\n */\n\nimport type {\n GrpcCompleteRequest,\n GrpcEnqueueRequest,\n GrpcFailRequest,\n GrpcJob,\n GrpcProcessRequest,\n GrpcProcessResponse,\n} from \"./types.js\";\n\n/**\n * Default `retry` to true (callers opt out with an explicit `retry: false`).\n *\n * The proto declares `optional bool retry = 4`, so an explicit `false` goes on\n * the wire with presence and dead-letters the job now, and `true` retries it\n * until its `maxRetries` run out. The default is sent explicitly rather than\n * left off: servers before API 0.1.118 declared a plain `bool`, read an absent\n * field as `false` and dead-lettered the job on its first failure.\n */\nexport function encodeFailRequest(params: GrpcFailRequest): GrpcFailRequest {\n return { ...params, retry: params.retry ?? true };\n}\n\ntype ProtobufValue =\n | { nullValue: 0 }\n | { numberValue: number }\n | { stringValue: string }\n | { boolValue: boolean }\n | { structValue: ProtobufStruct }\n | { listValue: { values: ProtobufValue[] } };\n\ninterface ProtobufStruct {\n fields: Record<string, ProtobufValue>;\n}\n\nfunction encodeStruct(\n value: Record<string, unknown> | null | undefined,\n): ProtobufStruct | undefined {\n if (value == null) {\n return undefined;\n }\n return {\n fields: Object.fromEntries(\n Object.entries(value).map(([key, entry]) => [key, encodeValue(entry)]),\n ),\n };\n}\n\nfunction encodeValue(value: unknown): ProtobufValue {\n if (value == null) {\n return { nullValue: 0 };\n }\n if (Array.isArray(value)) {\n return { listValue: { values: value.map(encodeValue) } };\n }\n switch (typeof value) {\n case \"number\":\n return { numberValue: value };\n case \"string\":\n return { stringValue: value };\n case \"boolean\":\n return { boolValue: value };\n case \"object\":\n return { structValue: encodeStruct(value as Record<string, unknown>)! };\n default:\n return { stringValue: String(value) };\n }\n}\n\nfunction decodeStruct(\n value: unknown,\n): Record<string, unknown> | null | undefined {\n if (!value || typeof value !== \"object\" || !(\"fields\" in value)) {\n return value as Record<string, unknown> | null | undefined;\n }\n const fields = (value as ProtobufStruct).fields ?? {};\n return Object.fromEntries(\n Object.entries(fields).map(([key, entry]) => [key, decodeValue(entry)]),\n );\n}\n\nfunction decodeValue(value: ProtobufValue): unknown {\n if (\"nullValue\" in value) {\n return null;\n }\n if (\"numberValue\" in value) {\n return value.numberValue;\n }\n if (\"stringValue\" in value) {\n return value.stringValue;\n }\n if (\"boolValue\" in value) {\n return value.boolValue;\n }\n if (\"structValue\" in value) {\n return decodeStruct(value.structValue);\n }\n if (\"listValue\" in value) {\n return (value.listValue.values ?? []).map(decodeValue);\n }\n return undefined;\n}\n\nexport function encodeEnqueueRequest(\n params: GrpcEnqueueRequest,\n): GrpcEnqueueRequest {\n // Omit unset numeric fields so proto-loader `defaults: true` does not force\n // wire zeros for maxRetries/timeoutSeconds (server treats 0 as its default).\n const encoded: Record<string, unknown> = {\n queueName: params.queueName,\n payload: encodeStruct(params.payload),\n };\n if (params.priority !== undefined) {\n encoded.priority = params.priority;\n }\n if (params.maxRetries !== undefined) {\n encoded.maxRetries = params.maxRetries;\n }\n if (params.timeoutSeconds !== undefined) {\n encoded.timeoutSeconds = params.timeoutSeconds;\n }\n if (params.idempotencyKey !== undefined && params.idempotencyKey !== \"\") {\n encoded.idempotencyKey = params.idempotencyKey;\n }\n if (params.scheduledAt !== undefined) {\n encoded.scheduledAt = params.scheduledAt;\n }\n if (params.tags !== undefined) {\n encoded.tags = params.tags;\n }\n return encoded as unknown as GrpcEnqueueRequest;\n}\n\nexport function encodeCompleteRequest(\n params: GrpcCompleteRequest,\n): GrpcCompleteRequest {\n return {\n ...params,\n result: encodeStruct(params.result) as unknown as Record<string, unknown>,\n };\n}\n\nexport function decodeJob(job: GrpcJob): GrpcJob {\n return {\n ...job,\n // proto-loader keeps an enum number it does not know (a status added to\n // the server's proto after this SDK) as a number; keep it a string so\n // `status` always matches its type.\n status: typeof job.status === \"number\" ? String(job.status) : job.status,\n payload: decodeStruct(job.payload),\n result: decodeStruct(job.result),\n };\n}\n\n/**\n * Encode a ProcessJobs request: a `fail` gets the `retry` default and a\n * `complete` its `result` as a `google.protobuf.Struct`, as on the unary calls.\n */\nexport function encodeProcessRequest(\n request: GrpcProcessRequest,\n): GrpcProcessRequest {\n if (request.fail) {\n return { ...request, fail: encodeFailRequest(request.fail) };\n }\n if (request.complete) {\n return { ...request, complete: encodeCompleteRequest(request.complete) };\n }\n return request;\n}\n\n/** Decode a ProcessJobs response: its `job` like a unary Dequeue job. */\nexport function decodeProcessResponse(\n response: GrpcProcessResponse,\n): GrpcProcessResponse {\n return response.job\n ? { ...response, job: decodeJob(response.job) }\n : response;\n}\n","/**\n * gRPC Streaming Helpers\n *\n * Utilities for working with gRPC streaming in a TypeScript-friendly way.\n */\n\nimport type * as grpc from \"@grpc/grpc-js\";\nimport {\n decodeJob,\n decodeProcessResponse,\n encodeProcessRequest,\n} from \"./encode.js\";\nimport type {\n GrpcJob,\n GrpcProcessRequest,\n GrpcProcessResponse,\n} from \"./types.js\";\n\n/**\n * Options for streaming operations\n */\nexport interface StreamOptions {\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n /** Called when connection is established */\n onConnected?: () => void;\n /** Called when an error occurs */\n onError?: (error: Error) => void;\n /** Called when the stream ends */\n onEnd?: () => void;\n}\n\n/**\n * Async iterable wrapper for gRPC readable streams (server streaming).\n */\nexport async function* asyncIterableFromStream<T>(\n stream: grpc.ClientReadableStream<T>,\n options?: StreamOptions,\n): AsyncGenerator<T, void, undefined> {\n const { signal, onConnected, onError, onEnd } = options ?? {};\n\n // Handle abort signal\n if (signal) {\n signal.addEventListener(\"abort\", () => {\n stream.cancel();\n });\n }\n\n return yield* new AsyncIterableStream(stream, {\n onConnected,\n onError,\n onEnd,\n });\n}\n\n/**\n * AsyncIterable wrapper for grpc.ClientReadableStream\n */\nclass AsyncIterableStream<T> implements AsyncIterable<T> {\n private stream: grpc.ClientReadableStream<T>;\n private options: Omit<StreamOptions, \"signal\">;\n private readonly decode: (item: T) => T;\n\n constructor(\n stream: grpc.ClientReadableStream<T>,\n options: Omit<StreamOptions, \"signal\"> = {},\n decode: (item: T) => T = (item) => item,\n ) {\n this.stream = stream;\n this.options = options;\n this.decode = decode;\n }\n\n async *[Symbol.asyncIterator](): AsyncGenerator<T, void, undefined> {\n const { onConnected, onError, onEnd } = this.options;\n const queue: T[] = [];\n let error: Error | null = null;\n let ended = false;\n let decodeFailed = false;\n let resolve: (() => void) | null = null;\n\n this.stream.on(\"data\", (data: T) => {\n // After a decode failure the stream is being cancelled; what the server\n // still has in flight is dropped, so no item is yielded out of order.\n if (decodeFailed) {\n return;\n }\n try {\n queue.push(this.decode(data));\n } catch (decodeError) {\n decodeFailed = true;\n error =\n decodeError instanceof Error\n ? decodeError\n : new Error(String(decodeError));\n // The iteration ends with this error, so stop the call instead of\n // leaving it open and receiving jobs nobody reads.\n try {\n this.stream.cancel?.();\n } catch {\n // The decode error is the one to report.\n }\n }\n resolve?.();\n });\n\n this.stream.on(\"error\", (err: Error) => {\n // The CANCELLED error our own cancel() causes must not replace the\n // decode error or reach onError.\n if (decodeFailed) {\n return;\n }\n error = err;\n onError?.(err);\n resolve?.();\n });\n\n this.stream.on(\"end\", () => {\n ended = true;\n onEnd?.();\n resolve?.();\n });\n\n this.stream.on(\"status\", (status: grpc.StatusObject) => {\n if (status.code === 0) {\n onConnected?.();\n }\n });\n\n while (true) {\n if (queue.length > 0) {\n yield queue.shift()!;\n continue;\n }\n\n if (error) {\n throw error;\n }\n\n if (ended) {\n return;\n }\n\n // Wait for next event\n await new Promise<void>((r) => {\n resolve = r;\n });\n }\n }\n}\n\n/**\n * Bidirectional stream wrapper for ProcessJobs\n */\nexport interface ProcessJobsStream {\n /** Send a request to the server */\n send(request: GrpcProcessRequest): void;\n /** Get async iterable for receiving responses */\n receive(): AsyncIterable<GrpcProcessResponse>;\n /** Signal that no more requests will be sent */\n end(): void;\n /** Cancel the stream */\n cancel(): void;\n}\n\n/**\n * Create a ProcessJobsStream from a gRPC duplex stream\n */\nexport function createProcessJobsStream(\n call: grpc.ClientDuplexStream<GrpcProcessRequest, GrpcProcessResponse>,\n options?: StreamOptions,\n): ProcessJobsStream {\n const { signal, onError, onEnd } = options ?? {};\n\n // Handle abort signal\n if (signal) {\n signal.addEventListener(\"abort\", () => {\n call.cancel();\n });\n }\n\n return {\n send(request: GrpcProcessRequest): void {\n call.write(encodeProcessRequest(request));\n },\n\n receive(): AsyncIterable<GrpcProcessResponse> {\n return new AsyncIterableStream(\n call,\n { onError, onEnd },\n decodeProcessResponse,\n );\n },\n\n end(): void {\n call.end();\n },\n\n cancel(): void {\n call.cancel();\n },\n };\n}\n\n/**\n * Job stream for server-side streaming (StreamJobs)\n */\nexport interface JobStream extends AsyncIterable<GrpcJob> {\n /** Cancel the stream */\n cancel(): void;\n}\n\n/**\n * Create a JobStream from a gRPC server stream\n */\nexport function createJobStream(\n call: grpc.ClientReadableStream<GrpcJob>,\n options?: StreamOptions,\n): JobStream {\n const { signal, onConnected, onError, onEnd } = options ?? {};\n\n // Handle abort signal\n if (signal) {\n signal.addEventListener(\"abort\", () => {\n call.cancel();\n });\n }\n\n const iterable = new AsyncIterableStream<GrpcJob>(\n call,\n { onConnected, onError, onEnd },\n decodeJob,\n );\n\n return {\n [Symbol.asyncIterator]() {\n return iterable[Symbol.asyncIterator]();\n },\n cancel() {\n call.cancel();\n },\n };\n}\n","/**\n * gRPC Client\n *\n * Real gRPC client using @grpc/grpc-js for HTTP/2 + Protobuf communication.\n * Supports unary calls, server streaming, and bidirectional streaming.\n */\n\nimport * as grpc from \"@grpc/grpc-js\";\nimport { loadProtoDefinition } from \"./loader.js\";\nimport {\n decodeJob,\n encodeCompleteRequest,\n encodeEnqueueRequest,\n encodeFailRequest,\n} from \"./encode.js\";\nimport {\n createJobStream,\n createProcessJobsStream,\n type JobStream,\n type ProcessJobsStream,\n type StreamOptions,\n} from \"./streaming.js\";\nimport type {\n GrpcClientOptions,\n GrpcEnqueueRequest,\n GrpcEnqueueResponse,\n GrpcDequeueRequest,\n GrpcDequeueResponse,\n GrpcCompleteRequest,\n GrpcCompleteResponse,\n GrpcFailRequest,\n GrpcFailResponse,\n GrpcRenewLeaseRequest,\n GrpcRenewLeaseResponse,\n GrpcGetJobRequest,\n GrpcGetJobResponse,\n GrpcGetQueueStatsRequest,\n GrpcGetQueueStatsResponse,\n GrpcStreamJobsRequest,\n GrpcRegisterWorkerRequest,\n GrpcRegisterWorkerResponse,\n GrpcHeartbeatRequest,\n GrpcHeartbeatResponse,\n GrpcDeregisterRequest,\n GrpcDeregisterResponse,\n GrpcProcessRequest,\n GrpcProcessResponse,\n GrpcJob,\n} from \"./types.js\";\nimport {\n AuthenticationError,\n AuthorizationError,\n ConflictError,\n NetworkError,\n NotFoundError,\n RateLimitError,\n ServerError,\n TimeoutError,\n ValidationError,\n} from \"../errors.js\";\n\n// Type definitions for dynamic gRPC clients\ntype UnaryCallback<T> = (error: grpc.ServiceError | null, response: T) => void;\ntype UnaryMethod<TReq, TRes> = {\n (request: TReq, metadata: grpc.Metadata, callback: UnaryCallback<TRes>): void;\n (\n request: TReq,\n metadata: grpc.Metadata,\n options: grpc.CallOptions,\n callback: UnaryCallback<TRes>,\n ): void;\n};\n\ninterface QueueServiceClient extends grpc.Client {\n Enqueue: UnaryMethod<GrpcEnqueueRequest, GrpcEnqueueResponse>;\n Dequeue: UnaryMethod<GrpcDequeueRequest, GrpcDequeueResponse>;\n Complete: UnaryMethod<GrpcCompleteRequest, GrpcCompleteResponse>;\n Fail: UnaryMethod<GrpcFailRequest, GrpcFailResponse>;\n RenewLease: UnaryMethod<GrpcRenewLeaseRequest, GrpcRenewLeaseResponse>;\n GetJob: UnaryMethod<GrpcGetJobRequest, GrpcGetJobResponse>;\n GetQueueStats: UnaryMethod<\n GrpcGetQueueStatsRequest,\n GrpcGetQueueStatsResponse\n >;\n StreamJobs(\n request: GrpcStreamJobsRequest,\n metadata: grpc.Metadata,\n ): grpc.ClientReadableStream<GrpcJob>;\n ProcessJobs(\n metadata: grpc.Metadata,\n ): grpc.ClientDuplexStream<GrpcProcessRequest, GrpcProcessResponse>;\n}\n\ninterface WorkerServiceClient extends grpc.Client {\n Register: UnaryMethod<GrpcRegisterWorkerRequest, GrpcRegisterWorkerResponse>;\n Heartbeat: UnaryMethod<GrpcHeartbeatRequest, GrpcHeartbeatResponse>;\n Deregister: UnaryMethod<GrpcDeregisterRequest, GrpcDeregisterResponse>;\n}\n\n/**\n * Wrap a callback-based gRPC call in a Promise\n */\nfunction promisify<TReq, TRes>(\n client: grpc.Client,\n method: UnaryMethod<TReq, TRes>,\n request: TReq,\n metadata: grpc.Metadata,\n timeoutMs?: number,\n): Promise<TRes> {\n return new Promise((resolve, reject) => {\n const callback: UnaryCallback<TRes> = (error, response) => {\n if (error) {\n reject(mapGrpcError(error, timeoutMs));\n } else {\n resolve(response);\n }\n };\n\n method.call(\n client,\n request,\n metadata,\n createUnaryCallOptions(timeoutMs),\n callback,\n );\n });\n}\n\nfunction createUnaryCallOptions(timeoutMs?: number): grpc.CallOptions {\n if (timeoutMs === undefined) {\n return {};\n }\n return { deadline: new Date(Date.now() + timeoutMs) };\n}\n\nfunction mapGrpcError(error: grpc.ServiceError, timeoutMs?: number): Error {\n const message = error.details || error.message || \"gRPC request failed\";\n\n switch (error.code) {\n case grpc.status.DEADLINE_EXCEEDED:\n return new TimeoutError(message, timeoutMs ?? 0);\n case grpc.status.UNAUTHENTICATED:\n return new AuthenticationError(message, \"AUTHENTICATION_FAILED\");\n case grpc.status.PERMISSION_DENIED:\n return new AuthorizationError(message, \"ACCESS_DENIED\");\n case grpc.status.NOT_FOUND:\n return new NotFoundError(message, \"NOT_FOUND\");\n case grpc.status.INVALID_ARGUMENT:\n case grpc.status.OUT_OF_RANGE:\n return new ValidationError(message, \"VALIDATION_ERROR\");\n case grpc.status.ALREADY_EXISTS:\n case grpc.status.ABORTED:\n case grpc.status.FAILED_PRECONDITION:\n return new ConflictError(message, \"CONFLICT\");\n case grpc.status.RESOURCE_EXHAUSTED:\n return new RateLimitError(message, \"RATE_LIMIT_EXCEEDED\");\n case grpc.status.UNAVAILABLE:\n case grpc.status.CANCELLED:\n return new NetworkError(message, error);\n default:\n if (error.code >= grpc.status.INTERNAL) {\n return new ServerError(message, 500, \"GRPC_SERVER_ERROR\");\n }\n return new ServerError(message, 500, \"GRPC_ERROR\");\n }\n}\n\n/** Host part of a `host:port` address, including bracketed IPv6 (`[::1]:50051`). */\nfunction grpcHost(address: string): string {\n if (address.startsWith(\"[\")) {\n const end = address.indexOf(\"]\");\n return end === -1 ? address : address.slice(1, end);\n }\n // A bare IPv6 literal has several colons and no port to strip.\n return address.split(\":\").length > 2 ? address : address.split(\":\")[0];\n}\n\n/**\n * Determine if TLS should be used based on address\n */\nfunction shouldUseTls(address: string, explicitTls?: boolean): boolean {\n if (explicitTls !== undefined) {\n return explicitTls;\n }\n // Default to insecure for localhost/127.0.0.1\n const host = grpcHost(address).toLowerCase();\n return host !== \"localhost\" && host !== \"127.0.0.1\" && host !== \"::1\";\n}\n\n/**\n * Queue operations for the gRPC client\n */\nexport class GrpcQueueOperations {\n constructor(\n private readonly client: QueueServiceClient,\n private readonly metadata: grpc.Metadata,\n private readonly timeoutMs?: number,\n ) {}\n\n /**\n * Enqueue a new job\n */\n async enqueue(params: GrpcEnqueueRequest): Promise<GrpcEnqueueResponse> {\n return promisify(\n this.client,\n this.client.Enqueue,\n encodeEnqueueRequest(params),\n this.metadata,\n this.timeoutMs,\n );\n }\n\n /**\n * Dequeue a job (for workers)\n */\n async dequeue(params: GrpcDequeueRequest): Promise<GrpcDequeueResponse> {\n const response = await promisify(\n this.client,\n this.client.Dequeue,\n params,\n this.metadata,\n this.timeoutMs,\n );\n return { ...response, jobs: response.jobs.map(decodeJob) };\n }\n\n /**\n * Complete a job successfully\n */\n async complete(params: GrpcCompleteRequest): Promise<GrpcCompleteResponse> {\n return promisify(\n this.client,\n this.client.Complete,\n encodeCompleteRequest(params),\n this.metadata,\n this.timeoutMs,\n );\n }\n\n /**\n * Fail a job\n */\n async fail(params: GrpcFailRequest): Promise<GrpcFailResponse> {\n return promisify(\n this.client,\n this.client.Fail,\n encodeFailRequest(params),\n this.metadata,\n this.timeoutMs,\n );\n }\n\n /**\n * Renew a job's lease\n */\n async renewLease(\n params: GrpcRenewLeaseRequest,\n ): Promise<GrpcRenewLeaseResponse> {\n return promisify(\n this.client,\n this.client.RenewLease,\n params,\n this.metadata,\n this.timeoutMs,\n );\n }\n\n /**\n * Get a job by ID\n */\n async getJob(jobId: string): Promise<GrpcGetJobResponse> {\n const response = await promisify(\n this.client,\n this.client.GetJob,\n { jobId },\n this.metadata,\n this.timeoutMs,\n );\n return {\n ...response,\n job: response.job ? decodeJob(response.job) : response.job,\n };\n }\n\n /**\n * Get queue statistics\n */\n async getQueueStats(queueName: string): Promise<GrpcGetQueueStatsResponse> {\n return promisify(\n this.client,\n this.client.GetQueueStats,\n { queueName },\n this.metadata,\n this.timeoutMs,\n );\n }\n\n /**\n * Stream jobs from a queue (server-side streaming)\n *\n * @example\n * ```typescript\n * const stream = client.grpc.queue.streamJobs({\n * queueName: 'my-queue',\n * workerId: 'worker-1',\n * });\n *\n * for await (const job of stream) {\n * console.log('Received job:', job.id);\n * }\n * ```\n */\n streamJobs(\n params: GrpcStreamJobsRequest,\n options?: StreamOptions,\n ): JobStream {\n const call = this.client.StreamJobs(params, this.metadata);\n return createJobStream(call, options);\n }\n\n /**\n * Open a bidirectional stream for processing jobs\n *\n * @example\n * ```typescript\n * const stream = client.grpc.queue.processJobs();\n *\n * // Request jobs\n * stream.send({ dequeue: { queueName: 'my-queue', workerId: 'worker-1' } });\n *\n * // Process responses\n * for await (const response of stream.receive()) {\n * if (response.job) {\n * // Process the job\n * stream.send({ complete: { jobId: response.job.id, workerId: 'worker-1' } });\n * }\n * }\n *\n * stream.end();\n * ```\n */\n processJobs(options?: StreamOptions): ProcessJobsStream {\n const call = this.client.ProcessJobs(this.metadata);\n return createProcessJobsStream(call, options);\n }\n}\n\n/**\n * Worker operations for the gRPC client\n */\nexport class GrpcWorkerOperations {\n constructor(\n private readonly client: WorkerServiceClient,\n private readonly metadata: grpc.Metadata,\n private readonly timeoutMs?: number,\n ) {}\n\n /**\n * Register a new worker\n */\n async register(\n params: GrpcRegisterWorkerRequest,\n ): Promise<GrpcRegisterWorkerResponse> {\n return promisify(\n this.client,\n this.client.Register,\n params,\n this.metadata,\n this.timeoutMs,\n );\n }\n\n /**\n * Send heartbeat\n */\n async heartbeat(\n params: GrpcHeartbeatRequest,\n ): Promise<GrpcHeartbeatResponse> {\n return promisify(\n this.client,\n this.client.Heartbeat,\n params,\n this.metadata,\n this.timeoutMs,\n );\n }\n\n /**\n * Deregister a worker\n */\n async deregister(workerId: string): Promise<GrpcDeregisterResponse> {\n return promisify(\n this.client,\n this.client.Deregister,\n { workerId },\n this.metadata,\n this.timeoutMs,\n );\n }\n}\n\n/**\n * Spooled gRPC Client\n *\n * Real gRPC client for high-performance job queue operations.\n *\n * @example\n * ```typescript\n * const client = new SpooledGrpcClient({\n * address: 'grpc.spooled.cloud:443',\n * apiKey: 'sk_live_...',\n * });\n *\n * // Enqueue a job\n * const { jobId } = await client.queue.enqueue({\n * queueName: 'my-queue',\n * payload: { message: 'Hello!' },\n * });\n *\n * // Stream jobs\n * for await (const job of client.queue.streamJobs({\n * queueName: 'my-queue',\n * workerId: 'worker-1',\n * })) {\n * console.log('Job:', job);\n * }\n * ```\n */\nexport class SpooledGrpcClient {\n private readonly queueClient: QueueServiceClient;\n private readonly workerClient: WorkerServiceClient;\n private readonly metadata: grpc.Metadata;\n\n /** Queue operations */\n readonly queue: GrpcQueueOperations;\n\n /** Worker operations */\n readonly workers: GrpcWorkerOperations;\n\n constructor(options: GrpcClientOptions) {\n const { address, apiKey, useTls, credentials, channelOptions, timeout } =\n options;\n\n // Create credentials\n const creds =\n credentials ??\n (shouldUseTls(address, useTls)\n ? grpc.credentials.createSsl()\n : grpc.credentials.createInsecure());\n\n // Create metadata with API key\n this.metadata = new grpc.Metadata();\n this.metadata.add(\"x-api-key\", apiKey);\n\n // Load proto definition\n const proto = loadProtoDefinition();\n\n // Create service clients\n this.queueClient = new proto.spooled.v1.QueueService(\n address,\n creds,\n channelOptions,\n ) as unknown as QueueServiceClient;\n\n this.workerClient = new proto.spooled.v1.WorkerService(\n address,\n creds,\n channelOptions,\n ) as unknown as WorkerServiceClient;\n\n // Initialize operation namespaces\n this.queue = new GrpcQueueOperations(\n this.queueClient,\n this.metadata,\n timeout,\n );\n this.workers = new GrpcWorkerOperations(\n this.workerClient,\n this.metadata,\n timeout,\n );\n }\n\n /**\n * Close all gRPC connections\n */\n close(): void {\n this.queueClient.close();\n this.workerClient.close();\n }\n\n /**\n * Wait for the clients to be ready\n */\n async waitForReady(deadline?: Date): Promise<void> {\n const d = deadline ?? new Date(Date.now() + 10000);\n await Promise.all([\n new Promise<void>((resolve, reject) => {\n this.queueClient.waitForReady(d, (error) => {\n if (error) reject(error);\n else resolve();\n });\n }),\n new Promise<void>((resolve, reject) => {\n this.workerClient.waitForReady(d, (error) => {\n if (error) reject(error);\n else resolve();\n });\n }),\n ]);\n }\n\n /**\n * Get the current connection state\n */\n getState(tryToConnect?: boolean): grpc.connectivityState {\n return this.queueClient\n .getChannel()\n .getConnectivityState(tryToConnect ?? false);\n }\n}\n","/**\n * Spooled Client\n *\n * Main entry point for the Spooled SDK.\n */\n\nimport {\n type SpooledClientConfig,\n type ResolvedConfig,\n resolveConfig,\n validateConfig,\n} from \"./config.js\";\nimport { AuthenticationError, type RateLimitInfo } from \"./errors.js\";\nimport { HttpClient, createHttpClient } from \"./utils/http.js\";\nimport {\n CircuitBreaker,\n createCircuitBreaker,\n} from \"./utils/circuit-breaker.js\";\nimport {\n AuthResource,\n JobsResource,\n QueuesResource,\n WorkersResource,\n SchedulesResource,\n WorkflowsResource,\n WebhooksResource,\n ApiKeysResource,\n OrganizationsResource,\n BillingResource,\n DashboardResource,\n HealthResource,\n MetricsResource,\n AdminResource,\n WebhookIngestionResource,\n} from \"./resources/index.js\";\nimport { SpooledRealtime } from \"./realtime/index.js\";\nimport type { SpooledRealtimeOptions } from \"./realtime/index.js\";\nimport { SpooledGrpcClient } from \"./grpc/client.js\";\n\n/**\n * Spooled Cloud SDK Client\n *\n * @example\n * ```typescript\n * const client = new SpooledClient({\n * apiKey: 'sk_live_...'\n * });\n *\n * // Create a job\n * const result = await client.jobs.create({\n * queueName: 'my-queue',\n * payload: { message: 'Hello, World!' }\n * });\n *\n * // List queues\n * const queues = await client.queues.list();\n * ```\n */\nexport class SpooledClient {\n private readonly config: ResolvedConfig;\n private readonly http: HttpClient;\n private readonly circuitBreaker: CircuitBreaker;\n private _grpc: SpooledGrpcClient | null = null;\n\n /** Authentication operations */\n readonly auth: AuthResource;\n\n /** Job operations */\n readonly jobs: JobsResource;\n\n /** Queue operations */\n readonly queues: QueuesResource;\n\n /** Worker operations */\n readonly workers: WorkersResource;\n\n /** Schedule operations */\n readonly schedules: SchedulesResource;\n\n /** Workflow operations */\n readonly workflows: WorkflowsResource;\n\n /** Outgoing webhook operations */\n readonly webhooks: WebhooksResource;\n\n /** API key operations */\n readonly apiKeys: ApiKeysResource;\n\n /** Organization operations */\n readonly organizations: OrganizationsResource;\n\n /** Billing operations */\n readonly billing: BillingResource;\n\n /** Dashboard operations */\n readonly dashboard: DashboardResource;\n\n /** Health endpoints (public) */\n readonly health: HealthResource;\n\n /** Metrics endpoint (public) */\n readonly metrics: MetricsResource;\n\n /** Admin endpoints (requires adminKey) */\n readonly admin: AdminResource;\n\n /** Webhook ingestion endpoints (signature-based) */\n readonly ingest: WebhookIngestionResource;\n\n /** Token refresh state */\n private refreshPromise: Promise<string> | null = null;\n private tokenExpiresAt: number | null = null;\n\n /**\n * Cached JWT for realtime connections (API-key auth path).\n *\n * The realtime layer requests a token on every (re)connect. Minting a brand\n * new JWT via POST /auth/login each time trips the login rate limit (429)\n * under a reconnect storm, after which realtime can never recover. We cache\n * the token here — at the client level, shared across reconnects — and reuse\n * it until it nears expiry.\n */\n private cachedJwt: string | null = null;\n /** Deduplicates concurrent logins (e.g. WS + SSE reconnecting together). */\n private jwtLoginPromise: Promise<string> | null = null;\n\n constructor(options: SpooledClientConfig) {\n // Resolve and validate configuration\n this.config = resolveConfig(options);\n validateConfig(this.config);\n\n // Create circuit breaker\n this.circuitBreaker = createCircuitBreaker(this.config.circuitBreaker);\n\n // Create HTTP client\n this.http = createHttpClient(this.config, this.circuitBreaker);\n\n // Set up token refresh if using JWT\n if (\n this.config.accessToken &&\n this.config.refreshToken &&\n this.config.autoRefreshToken\n ) {\n this.http.setRefreshTokenFn(this.refreshAccessToken.bind(this));\n }\n\n // Create resource instances\n this.auth = new AuthResource(this.http, () => this.config.refreshToken);\n this.jobs = new JobsResource(this.http);\n this.queues = new QueuesResource(this.http);\n this.workers = new WorkersResource(this.http);\n this.schedules = new SchedulesResource(this.http);\n this.workflows = new WorkflowsResource(this.http);\n this.webhooks = new WebhooksResource(this.http);\n this.apiKeys = new ApiKeysResource(this.http);\n this.organizations = new OrganizationsResource(this.http);\n this.billing = new BillingResource(this.http);\n this.dashboard = new DashboardResource(this.http);\n this.health = new HealthResource(this.http);\n this.metrics = new MetricsResource(this.http);\n this.admin = new AdminResource(this.http, this.config.adminKey);\n this.ingest = new WebhookIngestionResource(this.http);\n\n this.config.debug?.(\"SpooledClient initialized\", {\n baseUrl: this.config.baseUrl,\n hasApiKey: !!this.config.apiKey,\n hasAccessToken: !!this.config.accessToken,\n });\n }\n\n /**\n * Real gRPC client for high-performance operations (HTTP/2 + Protobuf)\n *\n * The gRPC client is created lazily on first access to avoid\n * loading the proto file unless it's actually needed.\n *\n * @example\n * ```typescript\n * // Enqueue via gRPC\n * const { jobId } = await client.grpc.queue.enqueue({\n * queueName: 'my-queue',\n * payload: { message: 'Hello!' },\n * });\n *\n * // Stream jobs\n * for await (const job of client.grpc.queue.streamJobs({\n * queueName: 'my-queue',\n * workerId: 'worker-1',\n * })) {\n * console.log('Job:', job);\n * }\n * ```\n */\n get grpc(): SpooledGrpcClient {\n if (!this._grpc) {\n const grpcAddress = this.resolveGrpcAddress();\n const apiKey = this.config.apiKey;\n\n if (!apiKey) {\n throw new AuthenticationError(\"gRPC client requires an API key\");\n }\n\n this._grpc = new SpooledGrpcClient({\n address: grpcAddress,\n apiKey,\n timeout: this.config.timeout,\n });\n }\n return this._grpc;\n }\n\n /**\n * Create a realtime connection for WebSocket or SSE events\n *\n * @example\n * ```typescript\n * const realtime = await client.realtime();\n *\n * realtime.on('job.created', (event) => {\n * console.log('New job:', event.jobId);\n * });\n *\n * await realtime.connect();\n * await realtime.subscribe({ queueName: 'my-queue' });\n * ```\n */\n async realtime(options?: SpooledRealtimeOptions): Promise<SpooledRealtime> {\n // Get an initial JWT (fails fast on auth errors at call time).\n const token = await this.getJwtToken();\n\n return new SpooledRealtime({\n baseUrl: this.config.baseUrl,\n wsUrl: this.config.wsUrl,\n token,\n // Provider the realtime layer calls on every (re)connect. It returns a\n // cached JWT and only re-logs-in when the token is absent, near expiry,\n // or the transport asks to force a refresh (e.g. after a 401 upgrade).\n tokenProvider: (forceRefresh) => this.getJwtToken(forceRefresh),\n ...options,\n // Only forward debug when the client actually has a logger, so we never\n // hand the realtime layer an explicit `debug: undefined`. The WS/SSE\n // constructors also guard against this, but keeping the undefined out of\n // the option object makes the intent clear at the call site.\n ...(this.config.debug ? { debug: this.config.debug } : {}),\n });\n }\n\n /**\n * Get or acquire a JWT token for realtime connections.\n *\n * The realtime layer calls this on every (re)connect. We cache the JWT and\n * reuse it until it nears expiry so a reconnect storm doesn't hammer\n * /auth/login and trip its rate limit. A fresh login happens only when the\n * cached token is absent, within ~60s of its `exp`, or a refresh is forced.\n *\n * @param forceRefresh Bypass the cache and mint a new token. Set by the\n * transport when the server rejected the current token (e.g. a 401 on the\n * WebSocket upgrade), so a stale/revoked token is replaced without waiting\n * for it to expire.\n */\n private async getJwtToken(forceRefresh = false): Promise<string> {\n // A JWT access token supplied directly: reuse it, refreshing via the\n // refresh token when it nears expiry (or when a refresh is forced).\n if (this.config.accessToken) {\n if (forceRefresh || this.shouldRefreshToken()) {\n return this.refreshAccessToken();\n }\n return this.config.accessToken;\n }\n\n // API-key auth: exchange the key for a JWT once, then reuse the cached JWT\n // across (re)connects until it nears expiry. Only then log in again.\n if (this.config.apiKey) {\n if (forceRefresh) {\n this.cachedJwt = null;\n }\n if (this.cachedJwt && !isJwtNearExpiry(this.cachedJwt)) {\n return this.cachedJwt;\n }\n return this.loginForJwt();\n }\n\n throw new AuthenticationError(\n \"No authentication method available for realtime connection\",\n );\n }\n\n /**\n * Exchange the API key for a JWT via /auth/login and cache the result.\n *\n * The JWT belongs to the realtime transport only. It must NOT replace the\n * REST bearer: an API-key client has no refresh token wired into its HTTP\n * layer, so after the JWT's 24 h lifetime every REST call (claim, complete,\n * heartbeat, create) would have failed with 401 for good. REST keeps using\n * the API key; realtime re-mints its own JWT near expiry (see\n * `getJwtToken`).\n *\n * Concurrent callers share a single in-flight login so a burst of reconnects\n * (e.g. WebSocket and SSE at once) issues just one request.\n */\n private async loginForJwt(): Promise<string> {\n if (this.jwtLoginPromise) {\n return this.jwtLoginPromise;\n }\n\n this.jwtLoginPromise = (async () => {\n const response = await this.auth.login({ apiKey: this.config.apiKey! });\n\n // Cache the token for future (re)connects; leave `http` auth alone.\n this.cachedJwt = response.accessToken;\n\n return response.accessToken;\n })();\n\n try {\n return await this.jwtLoginPromise;\n } finally {\n this.jwtLoginPromise = null;\n }\n }\n\n /**\n * Check if token should be refreshed\n */\n private shouldRefreshToken(): boolean {\n if (!this.tokenExpiresAt) {\n return false;\n }\n // Refresh 5 minutes before expiry\n const bufferMs = 5 * 60 * 1000;\n return Date.now() >= this.tokenExpiresAt - bufferMs;\n }\n\n /**\n * Refresh the access token\n */\n private async refreshAccessToken(): Promise<string> {\n // Deduplicate concurrent refresh requests\n if (this.refreshPromise) {\n return this.refreshPromise;\n }\n\n if (!this.config.refreshToken) {\n throw new AuthenticationError(\"No refresh token available\");\n }\n\n this.refreshPromise = this.doRefreshToken();\n\n try {\n return await this.refreshPromise;\n } finally {\n this.refreshPromise = null;\n }\n }\n\n /**\n * Actually perform the token refresh\n */\n private async doRefreshToken(): Promise<string> {\n const response = await this.auth.refresh({\n refreshToken: this.config.refreshToken!,\n });\n\n // Update state\n this.http.setAuthToken(response.accessToken);\n this.tokenExpiresAt = Date.now() + response.expiresIn * 1000;\n (this.config as ResolvedConfig).accessToken = response.accessToken;\n\n this.config.debug?.(\"Token refreshed successfully\");\n\n return response.accessToken;\n }\n\n /**\n * Get current configuration (read-only)\n */\n getConfig(): Readonly<ResolvedConfig> {\n return this.config;\n }\n\n /**\n * Rate-limit state from the most recent response that carried\n * `X-RateLimit-*` headers (API 0.1.122+): `limit`, `remaining`, `reset`\n * (from the Unix-seconds header), `scope` and, after a 429, `retryAfter`.\n * `undefined` until such a response arrives, and for servers or routes that\n * do not send the headers. A 429 also carries the same values on\n * `RateLimitError.rateLimitInfo`.\n */\n getRateLimitInfo(): RateLimitInfo | undefined {\n return this.http.getLastRateLimitInfo();\n }\n\n /**\n * Get circuit breaker statistics\n */\n getCircuitBreakerStats() {\n return this.circuitBreaker.getStats();\n }\n\n /**\n * Reset the circuit breaker\n */\n resetCircuitBreaker(): void {\n this.circuitBreaker.reset();\n }\n\n /**\n * Create a new client with different options\n */\n withOptions(options: Partial<SpooledClientConfig>): SpooledClient {\n return new SpooledClient({\n apiKey: this.config.apiKey,\n accessToken: this.config.accessToken,\n refreshToken: this.config.refreshToken,\n adminKey: this.config.adminKey,\n grpcAddress: this.config.grpcAddress,\n baseUrl: this.config.baseUrl,\n timeout: this.config.timeout,\n retry: this.config.retry,\n circuitBreaker: this.config.circuitBreaker,\n headers: this.config.headers,\n fetch: this.config.fetch,\n userAgent: this.config.userAgent,\n debug: this.config.debug ?? undefined,\n autoRefreshToken: this.config.autoRefreshToken,\n ...options,\n });\n }\n\n /**\n * Resolve gRPC address (host:port format)\n */\n private resolveGrpcAddress(): string {\n return this.config.grpcAddress;\n }\n\n /**\n * Close all connections including gRPC\n */\n close(): void {\n if (this._grpc) {\n this._grpc.close();\n this._grpc = null;\n }\n }\n}\n\n/**\n * Create a new SpooledClient instance\n *\n * @example\n * ```typescript\n * const client = createClient({\n * apiKey: process.env.SPOOLED_API_KEY\n * });\n * ```\n */\nexport function createClient(options: SpooledClientConfig): SpooledClient {\n return new SpooledClient(options);\n}\n\n/**\n * Decode a JWT's `exp` claim (seconds since epoch) without verifying the\n * signature — we only need the expiry to decide when to refresh, not to trust\n * the token. Returns null for a malformed token or one with no numeric `exp`.\n */\nexport function decodeJwtExp(token: string): number | null {\n const parts = token.split(\".\");\n if (parts.length < 2) {\n return null;\n }\n try {\n const payload = JSON.parse(base64UrlDecode(parts[1])) as { exp?: unknown };\n return typeof payload.exp === \"number\" ? payload.exp : null;\n } catch {\n return null;\n }\n}\n\n/**\n * True when a token is missing an `exp` we can read or is within `skewMs` of it.\n * A token whose expiry can't be decoded is treated as expiring, so we fall back\n * to a fresh login rather than reuse a token we can't reason about.\n */\nexport function isJwtNearExpiry(token: string, skewMs = 60_000): boolean {\n const exp = decodeJwtExp(token);\n if (exp === null) {\n return true;\n }\n return Date.now() >= exp * 1000 - skewMs;\n}\n\n/** Base64url-decode a JWT segment to a UTF-8 string, across Node and browsers. */\nfunction base64UrlDecode(segment: string): string {\n const b64 = segment.replace(/-/g, \"+\").replace(/_/g, \"/\");\n // Prefer Node's Buffer; fall back to atob for browsers / non-Node runtimes.\n // Referenced via globalThis so neither global is a hard dependency.\n if (typeof globalThis.Buffer !== \"undefined\") {\n return globalThis.Buffer.from(b64, \"base64\").toString(\"utf8\");\n }\n const binary = globalThis.atob(b64);\n const bytes = Uint8Array.from(binary, (c) => c.charCodeAt(0));\n return new globalThis.TextDecoder().decode(bytes);\n}\n","/**\n * Common Types\n *\n * Shared types used across the SDK.\n */\n\n/** JSON primitive types */\nexport type JsonPrimitive = string | number | boolean | null;\n\n/**\n * JSON value type.\n *\n * Inside user-owned JSON (`payload`, `result`, `tags`, and the other\n * free-form fields) an integer whose magnitude is greater than 2^53 is\n * returned as a decimal string, so the digits survive decoding. A float64\n * cannot hold those integers, and a string is already a `JsonValue`. Every\n * smaller number, and every number outside those fields, stays a `number`.\n * gRPC payloads cannot do this: `google.protobuf.Struct` has already stored\n * the value as a float64.\n */\nexport type JsonValue = JsonPrimitive | JsonObject | JsonArray;\n\n/** JSON object type */\nexport interface JsonObject {\n [key: string]: JsonValue;\n}\n\n/** JSON array type */\nexport type JsonArray = JsonValue[];\n\n/** Job status enum values */\nexport type JobStatus =\n | \"pending\"\n | \"scheduled\"\n | \"processing\"\n | \"completed\"\n | \"failed\"\n | \"deadletter\"\n | \"cancelled\";\n\n/** Worker status enum values */\nexport type WorkerStatus = \"healthy\" | \"degraded\" | \"offline\" | \"draining\";\n\n/** Workflow status enum values */\nexport type WorkflowStatus =\n | \"pending\"\n | \"running\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\";\n\n/** Plan tier enum values */\nexport type PlanTier = \"free\" | \"starter\" | \"pro\" | \"enterprise\";\n\n/** Schedule run status */\nexport type ScheduleRunStatus = \"pending\" | \"running\" | \"completed\" | \"failed\";\n\n/** Webhook delivery status */\nexport type WebhookDeliveryStatus = \"pending\" | \"success\" | \"failed\";\n\n/**\n * Webhook event types.\n *\n * `job.deadlettered`, `job.retried`, `workflow.completed` and\n * `workflow.failed` need API 0.1.122 or later. The SDK does not check event\n * names in responses: a name newer than this list is passed through as a\n * string, so give a `switch` over it a `default` branch.\n */\nexport type WebhookEventType =\n | \"job.created\"\n | \"job.started\"\n | \"job.completed\"\n | \"job.failed\"\n | \"job.cancelled\"\n | \"queue.paused\"\n | \"queue.resumed\"\n | \"worker.registered\"\n | \"worker.deregistered\"\n | \"schedule.triggered\"\n /** Sent next to every `job.failed` whose `data.status` is `deadletter`. */\n | \"job.deadlettered\"\n /** A manual retry (job, DLQ or workflow retry) put the job back to pending. */\n | \"job.retried\"\n /** A workflow finished; announced at most once, up to ~10 s late. */\n | \"workflow.completed\"\n /** A workflow failed; announced at most once, up to ~10 s late. */\n | \"workflow.failed\";\n\n/**\n * Body format of an outgoing webhook (API 0.1.122+).\n *\n * `json` (the default) is the signed JSON envelope. `slack`, `discord` and\n * `teams` send one short chat message built from the event, so a chat\n * service's incoming-webhook URL can be used as it is (`teams` is the legacy\n * Office 365 connector `MessageCard`; Teams Workflows URLs reject it).\n */\nexport type WebhookFormat = \"json\" | \"slack\" | \"discord\" | \"teams\";\n\n/** Dependency mode for workflows */\nexport type DependencyMode = \"all\" | \"any\";\n\n/** Pagination parameters */\nexport interface PaginationParams {\n /** Maximum number of results */\n limit?: number;\n /** Offset for pagination */\n offset?: number;\n}\n\n/** List parameters with optional sorting */\nexport interface ListParams extends PaginationParams {\n /** Field to order by */\n orderBy?: string;\n /** Sort direction */\n orderDir?: \"asc\" | \"desc\";\n}\n\n/** Paginated response wrapper */\nexport interface PaginatedResponse<T> {\n /** Items in current page */\n data: T[];\n /** Total count (if available) */\n total?: number;\n /** Current page offset */\n offset: number;\n /** Page size limit */\n limit: number;\n /** Whether there are more results */\n hasMore: boolean;\n}\n\n/**\n * One page of a list endpoint that reports `X-Has-More` (API 0.1.122+):\n * `GET /jobs`, `GET /jobs/dlq` and `GET /jobs/{id}/history`.\n *\n * The response body stays a bare array; `hasMore` comes from the header.\n */\nexport interface ListPage<T> {\n /** Items of this page, in the server's order */\n data: T[];\n /**\n * `true` when another page follows: ask again with\n * `offset + data.length`. From the `X-Has-More` header; an older server\n * without it gets a guess from the page size (a full page means \"maybe\").\n */\n hasMore: boolean;\n}\n\n/**\n * Helper to create a paginated response from an array\n */\nexport function createPaginatedResponse<T>(\n items: T[],\n limit: number,\n offset: number = 0,\n total?: number,\n): PaginatedResponse<T> {\n return {\n data: items,\n total,\n offset,\n limit,\n hasMore: items.length === limit,\n };\n}\n","/**\n * gRPC Types\n *\n * Types that mirror the protobuf definitions in spooled.proto.\n * Uses proper enum names matching the proto (JOB_STATUS_PENDING, etc.)\n */\n\nimport type * as grpc from \"@grpc/grpc-js\";\n\n// ============================================================================\n// Job Status Enum\n// ============================================================================\n\n/** Job status enum values (proto-style naming) */\nexport enum GrpcJobStatus {\n JOB_STATUS_UNSPECIFIED = \"JOB_STATUS_UNSPECIFIED\",\n JOB_STATUS_PENDING = \"JOB_STATUS_PENDING\",\n JOB_STATUS_SCHEDULED = \"JOB_STATUS_SCHEDULED\",\n JOB_STATUS_PROCESSING = \"JOB_STATUS_PROCESSING\",\n JOB_STATUS_COMPLETED = \"JOB_STATUS_COMPLETED\",\n JOB_STATUS_FAILED = \"JOB_STATUS_FAILED\",\n JOB_STATUS_DEADLETTER = \"JOB_STATUS_DEADLETTER\",\n JOB_STATUS_CANCELLED = \"JOB_STATUS_CANCELLED\",\n}\n\n/** Numeric job status values (for backward compatibility) */\nexport const GrpcJobStatusNumber = {\n UNSPECIFIED: 0,\n PENDING: 1,\n SCHEDULED: 2,\n PROCESSING: 3,\n COMPLETED: 4,\n FAILED: 5,\n DEADLETTER: 6,\n CANCELLED: 7,\n} as const;\n\n// ============================================================================\n// Timestamp handling\n// ============================================================================\n\n/** Timestamp as returned by gRPC (can be object or ISO string) */\nexport interface GrpcTimestamp {\n seconds?: string | number;\n nanos?: number;\n}\n\n/** Convert timestamp to Date */\nexport function timestampToDate(\n ts: GrpcTimestamp | string | undefined | null,\n): Date | null {\n if (!ts) return null;\n\n if (typeof ts === \"string\") {\n return new Date(ts);\n }\n\n const seconds =\n typeof ts.seconds === \"string\"\n ? parseInt(ts.seconds, 10)\n : (ts.seconds ?? 0);\n const nanos = ts.nanos ?? 0;\n return new Date(seconds * 1000 + Math.floor(nanos / 1_000_000));\n}\n\n/** Convert Date to timestamp object */\nexport function dateToTimestamp(date: Date | string): GrpcTimestamp {\n const d = typeof date === \"string\" ? new Date(date) : date;\n const ms = d.getTime();\n return {\n seconds: Math.floor(ms / 1000).toString(),\n nanos: (ms % 1000) * 1_000_000,\n };\n}\n\n// ============================================================================\n// Job Message\n// ============================================================================\n\n/** Job message as returned by gRPC */\nexport interface GrpcJob {\n id: string;\n organizationId: string;\n queueName: string;\n status: GrpcJobStatus | string;\n /**\n * Payload as google.protobuf.Struct (object).\n *\n * Struct stores every number as a float64, so an integer above 2^53 is\n * already rounded before this SDK sees it. REST keeps those integers as\n * decimal strings; send them as strings on this path.\n */\n payload?: Record<string, unknown> | null;\n /**\n * Result as google.protobuf.Struct (object). Same float64 limit as\n * `payload`: an integer above 2^53 cannot round-trip.\n */\n result?: Record<string, unknown> | null;\n retryCount: number;\n maxRetries: number;\n lastError?: string | null;\n priority: number;\n timeoutSeconds: number;\n createdAt?: GrpcTimestamp | string | null;\n scheduledAt?: GrpcTimestamp | string | null;\n startedAt?: GrpcTimestamp | string | null;\n completedAt?: GrpcTimestamp | string | null;\n leaseExpiresAt?: GrpcTimestamp | string | null;\n assignedWorkerId?: string | null;\n idempotencyKey?: string | null;\n /**\n * Lease fencing token (proto `lease_id`). Returned on dequeue; echo it back\n * in Complete/Fail/RenewLease so the operation applies only to the lease\n * this worker actually holds (empty = legacy worker_id fence).\n */\n leaseId?: string | null;\n}\n\n// ============================================================================\n// Queue Service - Request/Response Types\n// ============================================================================\n\n/** Enqueue request */\nexport interface GrpcEnqueueRequest {\n queueName: string;\n /** Payload as object (will be converted to google.protobuf.Struct) */\n payload?: Record<string, unknown>;\n priority?: number;\n maxRetries?: number;\n timeoutSeconds?: number;\n scheduledAt?: GrpcTimestamp | string;\n idempotencyKey?: string;\n tags?: Record<string, string>;\n}\n\n/** Enqueue response */\nexport interface GrpcEnqueueResponse {\n jobId: string;\n created: boolean;\n}\n\n/** Dequeue request */\nexport interface GrpcDequeueRequest {\n queueName: string;\n workerId: string;\n leaseDurationSecs?: number;\n batchSize?: number;\n}\n\n/** Dequeue response */\nexport interface GrpcDequeueResponse {\n jobs: GrpcJob[];\n}\n\n/** Complete request */\nexport interface GrpcCompleteRequest {\n jobId: string;\n workerId: string;\n /** Result as object (will be converted to google.protobuf.Struct) */\n result?: Record<string, unknown>;\n /**\n * Lease fencing token from the dequeued job (proto `lease_id`). Required: the\n * server rejects a settlement without it with INVALID_ARGUMENT.\n */\n leaseId: string;\n}\n\n/** Complete response */\nexport interface GrpcCompleteResponse {\n success: boolean;\n}\n\n/** Fail request */\nexport interface GrpcFailRequest {\n jobId: string;\n workerId: string;\n error: string;\n /**\n * Retry the job (until its `maxRetries` run out) instead of dead-lettering it\n * at once. Defaults to `true`, which the SDK sends explicitly, so servers\n * from before proto field 4 became `optional bool` (where an absent field\n * read as `false` and dead-lettered the job on its first failure) behave the\n * same. Pass `false` to dead-letter the job now, whatever `maxRetries` says:\n * the SDK puts `retry = false` on the wire with field presence.\n */\n retry?: boolean;\n /**\n * Lease fencing token from the dequeued job (proto `lease_id`). Required: the\n * server rejects a settlement without it with INVALID_ARGUMENT.\n */\n leaseId: string;\n}\n\n/** Fail response */\nexport interface GrpcFailResponse {\n success: boolean;\n willRetry?: boolean;\n nextRetryDelaySecs?: number;\n}\n\n/** Renew lease request */\nexport interface GrpcRenewLeaseRequest {\n jobId: string;\n workerId: string;\n extensionSecs: number;\n /**\n * Lease fencing token from the dequeued job (proto `lease_id`). Required: the\n * server rejects a renewal without it with INVALID_ARGUMENT.\n */\n leaseId: string;\n}\n\n/** Renew lease response */\nexport interface GrpcRenewLeaseResponse {\n success: boolean;\n newExpiresAt?: GrpcTimestamp | string | null;\n}\n\n/** Get job request */\nexport interface GrpcGetJobRequest {\n jobId: string;\n}\n\n/** Get job response */\nexport interface GrpcGetJobResponse {\n job?: GrpcJob | null;\n}\n\n/** Get queue stats request */\nexport interface GrpcGetQueueStatsRequest {\n queueName: string;\n}\n\n/** Get queue stats response */\nexport interface GrpcGetQueueStatsResponse {\n queueName: string;\n pending: number | string;\n scheduled: number | string;\n processing: number | string;\n completed: number | string;\n failed: number | string;\n deadletter: number | string;\n total: number | string;\n maxAgeMs?: number | string | null;\n}\n\n/** Stream jobs request (server streaming) */\nexport interface GrpcStreamJobsRequest {\n queueName: string;\n workerId: string;\n leaseDurationSecs?: number;\n}\n\n// ============================================================================\n// Bidirectional Streaming Types\n// ============================================================================\n\n/** Process request (for bidirectional streaming) */\nexport interface GrpcProcessRequest {\n dequeue?: GrpcDequeueRequest;\n complete?: GrpcCompleteRequest;\n fail?: GrpcFailRequest;\n renewLease?: GrpcRenewLeaseRequest;\n}\n\n/** Error response */\nexport interface GrpcErrorResponse {\n code: string;\n message: string;\n}\n\n/** Process response (for bidirectional streaming) */\nexport interface GrpcProcessResponse {\n job?: GrpcJob;\n complete?: GrpcCompleteResponse;\n fail?: GrpcFailResponse;\n renewLease?: GrpcRenewLeaseResponse;\n error?: GrpcErrorResponse;\n}\n\n// ============================================================================\n// Worker Service Types\n// ============================================================================\n\n/** Register worker request */\nexport interface GrpcRegisterWorkerRequest {\n queueName: string;\n hostname?: string;\n workerType?: string;\n maxConcurrency?: number;\n version?: string;\n metadata?: Record<string, string>;\n /**\n * Stable worker id (proto `optional string worker_id = 7`): 1-128\n * characters, letters, digits, `-`, `_` and `.`.\n *\n * Send the same id after a restart and the server updates that worker\n * instead of adding one, so a restarting worker does not count twice against\n * the plan's worker limit. Omitted or empty: the server assigns a new id. An\n * id that another organization already uses fails with ALREADY_EXISTS\n * (`ConflictError`). Servers older than API 0.1.119 ignore the field.\n */\n workerId?: string;\n}\n\n/** Register worker response */\nexport interface GrpcRegisterWorkerResponse {\n workerId: string;\n leaseDurationSecs: number;\n heartbeatIntervalSecs: number;\n}\n\n/** Heartbeat request */\nexport interface GrpcHeartbeatRequest {\n workerId: string;\n currentJobs?: number;\n status?: string;\n metadata?: Record<string, string>;\n}\n\n/** Heartbeat response */\nexport interface GrpcHeartbeatResponse {\n acknowledged: boolean;\n shouldDrain?: boolean;\n}\n\n/** Deregister request */\nexport interface GrpcDeregisterRequest {\n workerId: string;\n}\n\n/** Deregister response */\nexport interface GrpcDeregisterResponse {\n success: boolean;\n}\n\n// ============================================================================\n// gRPC Client Options\n// ============================================================================\n\n/** Options for creating a gRPC client */\nexport interface GrpcClientOptions {\n /** gRPC server address (host:port) */\n address: string;\n /** API key for authentication */\n apiKey: string;\n /** Use TLS (default: true for production, false for localhost) */\n useTls?: boolean;\n /** Custom channel credentials */\n credentials?: grpc.ChannelCredentials;\n /** Channel options */\n channelOptions?: grpc.ChannelOptions;\n /** Deadline for unary gRPC calls in milliseconds. Streams are not bounded unless explicitly configured. */\n timeout?: number;\n}\n\n// ============================================================================\n// Legacy types (backward compatibility)\n// ============================================================================\n\n/** @deprecated Use GrpcEnqueueRequest */\nexport type GrpcEnqueueJobParams = GrpcEnqueueRequest & {\n organizationId?: string;\n};\n\n/** @deprecated Use GrpcEnqueueResponse */\nexport type GrpcEnqueueJobResponse = GrpcEnqueueResponse;\n\n/** @deprecated Use GrpcDequeueRequest */\nexport type GrpcDequeueJobParams = GrpcDequeueRequest & {\n organizationId?: string;\n leaseDurationSeconds?: number;\n};\n\n/** @deprecated Use GrpcDequeueResponse */\nexport interface GrpcDequeueJobResponse {\n job?: GrpcJob | null;\n}\n\n/** @deprecated Use GrpcCompleteRequest */\nexport type GrpcCompleteJobParams = GrpcCompleteRequest;\n\n/** @deprecated Use GrpcCompleteResponse */\nexport type GrpcCompleteJobResponse = GrpcCompleteResponse;\n\n/** @deprecated Use GrpcFailRequest */\nexport interface GrpcFailJobParams {\n jobId: string;\n workerId: string;\n errorMessage: string;\n}\n\n/** @deprecated Use GrpcFailResponse */\nexport type GrpcFailJobResponse = GrpcFailResponse;\n\n/** @deprecated Use GrpcRenewLeaseRequest */\nexport interface GrpcRenewLeaseParams {\n jobId: string;\n workerId: string;\n leaseDurationSeconds: number;\n}\n\n/** @deprecated Use GrpcRenewLeaseResponse */\nexport interface GrpcRenewLeaseResponse_Legacy {\n renewed: boolean;\n newLeaseExpiresAt?: string | null;\n}\n\n/** @deprecated Use GrpcGetQueueStatsResponse */\nexport interface GrpcGetQueueStatsResponse_Legacy {\n queueName: string;\n pending: number;\n scheduled: number;\n processing: number;\n completed: number;\n failed: number;\n deadletter: number;\n total: number;\n maxAgeMs?: number | null;\n}\n\n/** @deprecated Use GrpcRegisterWorkerRequest */\nexport interface GrpcRegisterWorkerParams {\n workerId: string;\n organizationId?: string;\n queueNames: string[];\n maxConcurrentJobs?: number;\n hostname?: string;\n metadata?: Record<string, unknown> | string;\n}\n\n/** @deprecated Use GrpcRegisterWorkerResponse */\nexport interface GrpcRegisterWorkerResponse_Legacy {\n registered: boolean;\n heartbeatIntervalSeconds: number;\n}\n\n/** @deprecated Use GrpcHeartbeatRequest */\nexport interface GrpcHeartbeatParams {\n workerId: string;\n currentJobIds: string[];\n status: string;\n}\n\n/** @deprecated Use GrpcHeartbeatResponse */\nexport type GrpcHeartbeatResponse_Legacy = GrpcHeartbeatResponse;\n","/**\n * Spooled Worker\n *\n * Worker runtime for processing jobs from a queue.\n */\n\nimport type { SpooledClient } from \"../client.js\";\nimport { SDK_VERSION } from \"../config.js\";\nimport { SpooledError } from \"../errors.js\";\nimport type { JsonValue } from \"../types/common.js\";\nimport type { ClaimedJob } from \"../types/jobs.js\";\nimport { coerceFailureMessage } from \"../utils/failure.js\";\nimport type {\n SpooledWorkerOptions,\n WorkerState,\n JobHandler,\n JobContext,\n WorkerEvent,\n WorkerEventData,\n ActiveJob,\n} from \"./types.js\";\nimport { hostname as osHostname } from \"os\";\n\n/** Default options */\nconst DEFAULT_OPTIONS = {\n concurrency: 5,\n pollInterval: 1000,\n leaseDuration: 30,\n heartbeatFraction: 0.5,\n autoStart: false,\n shutdownTimeout: 30000,\n} as const;\n\n/** Event handler type */\ntype EventHandler<E extends WorkerEvent> = (data: WorkerEventData[E]) => void;\n\n/** Failure text sent when a handler outlives the job's `timeoutSeconds`. */\nconst JOB_TIMEOUT_MESSAGE = \"Job timeout exceeded\";\n\n/** Failure text sent for a handler still running when the shutdown grace ends. */\nconst SHUTDOWN_TIMEOUT_MESSAGE = \"Worker shutdown timeout\";\n\n/** Longest delay `setTimeout` accepts (a larger one fires immediately). */\nconst MAX_TIMER_MS = 2 ** 31 - 1;\n\n/** How a handler run ended. Decided once per execution. */\ntype HandlerOutcome =\n | { kind: \"returned\"; value: JsonValue | void }\n | { kind: \"threw\"; error: unknown }\n | { kind: \"timeout\" };\n\n/**\n * Spooled Worker\n *\n * @example\n * ```typescript\n * const worker = new SpooledWorker(client, {\n * queueName: 'my-queue',\n * concurrency: 10,\n * });\n *\n * worker.process(async (ctx) => {\n * console.log('Processing job:', ctx.jobId);\n * await doSomeWork(ctx.payload);\n * return { success: true };\n * });\n *\n * await worker.start();\n *\n * // Graceful shutdown\n * process.on('SIGTERM', () => worker.stop());\n * ```\n */\nexport class SpooledWorker {\n private readonly client: SpooledClient;\n /**\n * Options with every defaultable field filled in. `workerId` stays optional:\n * there is no sensible default for it, and omitting it is what makes the\n * server mint a UUID.\n */\n private readonly options: Required<Omit<SpooledWorkerOptions, \"workerId\">> &\n Pick<SpooledWorkerOptions, \"workerId\">;\n private readonly debug: (msg: string, meta?: unknown) => void;\n\n private state: WorkerState = \"idle\";\n private workerId: string | null = null;\n private handler: JobHandler | null = null;\n private activeJobs: Map<symbol, ActiveJob> = new Map();\n private pollTimer: ReturnType<typeof setTimeout> | null = null;\n private workerHeartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private shutdownPromise: Promise<void> | null = null;\n /** The claim request currently on the wire, so a stop can wait for its jobs. */\n private pollInFlight: Promise<void> | null = null;\n /** Wakes the shutdown drain when the last active job has been acked. */\n private drainWaiter: (() => void) | null = null;\n\n // Event handlers\n private eventHandlers: Map<WorkerEvent, Set<EventHandler<WorkerEvent>>> =\n new Map();\n\n constructor(client: SpooledClient, options: SpooledWorkerOptions) {\n this.client = client;\n this.options = {\n ...DEFAULT_OPTIONS,\n hostname: osHostname(),\n workerType: \"nodejs\",\n version: SDK_VERSION,\n metadata: {},\n ...options,\n } as Required<Omit<SpooledWorkerOptions, \"workerId\">> &\n Pick<SpooledWorkerOptions, \"workerId\">;\n\n // Get debug from client config\n const config = client.getConfig();\n this.debug = config.debug ?? (() => {});\n\n if (this.options.autoStart) {\n // Defer to next tick to allow process() to be called. start() already\n // reports a failed registration through the \"error\" event; the catch only\n // keeps it from becoming an unhandled rejection that crashes the process.\n setImmediate(() => {\n this.start().catch((error) => {\n this.debug(\"Auto-start failed\", error);\n });\n });\n }\n }\n\n /**\n * Get current worker state\n */\n getState(): WorkerState {\n return this.state;\n }\n\n /**\n * Get worker ID (available after start)\n */\n getWorkerId(): string | null {\n return this.workerId;\n }\n\n /**\n * Get number of active jobs\n */\n getActiveJobCount(): number {\n return this.activeJobs.size;\n }\n\n /**\n * Register job handler\n */\n process(handler: JobHandler): void {\n if (this.state !== \"idle\") {\n throw new Error(\"Cannot set handler after worker has started\");\n }\n this.handler = handler;\n }\n\n /**\n * Start the worker\n */\n async start(): Promise<void> {\n if (this.state !== \"idle\") {\n throw new Error(`Cannot start worker in state: ${this.state}`);\n }\n\n if (!this.handler) {\n throw new Error(\"No job handler registered. Call process() first.\");\n }\n\n this.state = \"starting\";\n this.debug(`Starting worker for queue: ${this.options.queueName}`);\n\n try {\n // Register with the API\n const registration = await this.client.workers.register({\n queueName: this.options.queueName,\n workerId: this.options.workerId,\n hostname: this.options.hostname,\n workerType: this.options.workerType,\n maxConcurrency: this.options.concurrency,\n metadata: this.options.metadata,\n version: this.options.version,\n });\n\n this.workerId = registration.id;\n this.debug(`Worker registered: ${this.workerId}`, registration);\n\n // Start worker heartbeat\n const heartbeatInterval = registration.heartbeatIntervalSecs * 1000;\n this.workerHeartbeatTimer = setInterval(() => {\n this.sendWorkerHeartbeat();\n }, heartbeatInterval);\n\n // Start polling\n this.state = \"running\";\n this.emit(\"started\", {\n workerId: this.workerId,\n queueName: this.options.queueName,\n });\n this.schedulePoll();\n } catch (error) {\n this.state = \"error\";\n this.emit(\"error\", { error: error as Error });\n throw error;\n }\n }\n\n /**\n * Stop the worker gracefully.\n *\n * Drains: the worker stops claiming, then lets running handlers finish for\n * up to `shutdownTimeout`. A handler that returns completes its job and one\n * that throws fails it, even though a stop was requested meanwhile; its\n * `signal` is NOT aborted during the grace period. Only handlers still\n * running when the timeout ends are aborted and failed with \"Worker shutdown\n * timeout\". The worker deregisters last, because deregistering returns every\n * job the worker still holds to the queue.\n */\n async stop(): Promise<void> {\n if (this.state !== \"running\") {\n return;\n }\n\n // Deduplicate concurrent stop calls\n if (this.shutdownPromise) {\n return this.shutdownPromise;\n }\n\n this.shutdownPromise = this.doStop();\n return this.shutdownPromise;\n }\n\n private async doStop(): Promise<void> {\n const deadline = Date.now() + this.options.shutdownTimeout;\n this.state = \"stopping\";\n this.debug(\"Stopping worker...\");\n\n // Stop polling\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n\n // A claim already on the wire still returns jobs this worker now holds\n // leases for. Let it land first so they join the drain below instead of\n // starting after the worker has deregistered.\n if (this.pollInFlight) {\n await this.pollInFlight;\n }\n\n // Drain: the worker heartbeat and every job heartbeat keep running while\n // handlers finish, so neither the worker nor a lease expires mid-drain.\n if (this.activeJobs.size > 0) {\n this.debug(\n `Waiting for ${this.activeJobs.size} active jobs to complete...`,\n );\n\n await this.waitForDrain(Math.max(0, deadline - Date.now()));\n\n // Whatever is still running outlived the grace period: abort and fail it.\n // A job whose handler returned just before the deadline is already\n // settled (its ack is in flight) and is awaited below, not failed.\n const stragglers = Array.from(this.activeJobs.values()).filter(\n (active) => !active.settled,\n );\n await Promise.all(stragglers.map((active) => this.abandonJob(active)));\n\n // Acks already on the wire must land before the worker deregisters,\n // otherwise deregistering re-queues a job that was just finished.\n await Promise.all(\n Array.from(this.activeJobs.values()).map((active) => active.ack),\n );\n }\n\n // Stop worker heartbeat\n if (this.workerHeartbeatTimer) {\n clearInterval(this.workerHeartbeatTimer);\n this.workerHeartbeatTimer = null;\n }\n\n // Deregister worker\n const workerId = this.workerId;\n if (workerId) {\n try {\n await this.client.workers.deregister(workerId);\n this.debug(\"Worker deregistered\");\n } catch (error) {\n this.debug(\"Failed to deregister worker\", error);\n }\n }\n\n this.state = \"stopped\";\n this.workerId = null;\n this.emit(\"stopped\", { workerId: workerId ?? \"\", reason: \"graceful\" });\n this.shutdownPromise = null;\n }\n\n /**\n * Add event listener\n */\n on<E extends WorkerEvent>(event: E, handler: EventHandler<E>): () => void {\n if (!this.eventHandlers.has(event)) {\n this.eventHandlers.set(event, new Set());\n }\n this.eventHandlers.get(event)!.add(handler as EventHandler<WorkerEvent>);\n return () => this.off(event, handler);\n }\n\n /**\n * Remove event listener\n */\n off<E extends WorkerEvent>(event: E, handler: EventHandler<E>): void {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.delete(handler as EventHandler<WorkerEvent>);\n }\n }\n\n // Private methods\n\n private emit<E extends WorkerEvent>(\n event: E,\n data: WorkerEventData[E],\n ): void {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n this.debug(\"Event handler error\", { event, error });\n }\n });\n }\n }\n\n private schedulePoll(): void {\n if (this.state !== \"running\") {\n return;\n }\n\n this.pollTimer = setTimeout(() => {\n this.pollTimer = null;\n const run = this.poll();\n this.pollInFlight = run;\n const done = () => {\n if (this.pollInFlight === run) {\n this.pollInFlight = null;\n }\n };\n run.then(done, done);\n }, this.options.pollInterval);\n }\n\n private async poll(): Promise<void> {\n if (this.state !== \"running\" || !this.workerId) {\n return;\n }\n\n // Check if we have capacity\n const availableSlots = this.options.concurrency - this.activeJobs.size;\n if (availableSlots <= 0) {\n this.schedulePoll();\n return;\n }\n\n try {\n // Claim jobs\n const result = await this.client.jobs.claim({\n queueName: this.options.queueName,\n workerId: this.workerId,\n limit: availableSlots,\n leaseDurationSecs: this.options.leaseDuration,\n });\n\n // Process claimed jobs\n for (const job of result.jobs) {\n this.processJob(job);\n }\n } catch (error) {\n this.debug(\"Poll failed\", error);\n this.emit(\"error\", { error: error as Error });\n }\n\n // Schedule next poll\n this.schedulePoll();\n }\n\n private processJob(job: ClaimedJob): void {\n this.emit(\"job:claimed\", { jobId: job.id, queueName: job.queueName });\n\n const abortController = new AbortController();\n const activeJob: ActiveJob = {\n executionId: Symbol(job.id),\n job,\n startedAt: new Date(),\n abortController,\n settled: false,\n };\n\n this.activeJobs.set(activeJob.executionId, activeJob);\n\n // Capture the immutable execution so a replacement lease cannot be borrowed.\n const heartbeatInterval =\n this.options.leaseDuration * this.options.heartbeatFraction * 1000;\n activeJob.heartbeatTimer = setInterval(() => {\n this.sendJobHeartbeat(activeJob);\n }, heartbeatInterval);\n\n // Execute handler\n this.executeHandler(activeJob);\n }\n\n private async executeHandler(activeJob: ActiveJob): Promise<void> {\n const { job, abortController } = activeJob;\n const { signal } = abortController;\n\n this.emit(\"job:started\", { jobId: job.id, queueName: job.queueName });\n\n const context: JobContext = {\n jobId: job.id,\n queueName: job.queueName,\n payload: job.payload,\n retryCount: job.retryCount,\n maxRetries: job.maxRetries,\n signal,\n progress: async (percent: number, message?: string) => {\n const boundedPercent = Math.max(0, Math.min(100, percent));\n this.debug(`[${job.id}] progress ${boundedPercent}%`, message);\n },\n log: (level, message, meta) => {\n this.debug(`[${job.id}] [${level}] ${message}`, meta);\n },\n };\n\n try {\n const outcome = await this.runHandler(activeJob, context);\n\n // A lost lease (heartbeat 409) means another worker may already be\n // running this job. Acking it would 409 and must not happen.\n if (activeJob.leaseLost) {\n this.debug(`Job ${job.id} lost its lease; dropping late result`);\n return;\n }\n // The shutdown drain already failed this job while its handler was still\n // running; the lease is gone, so a late result must not be sent.\n if (activeJob.settled) {\n this.debug(`Job ${job.id} was already settled; dropping late result`);\n return;\n }\n activeJob.settled = true;\n\n // The abort signal is only a hint to the handler. Whatever the handler\n // did decides the ack: a result that arrives after a stop was requested\n // is still sent, never silently dropped.\n switch (outcome.kind) {\n case \"returned\":\n activeJob.ack = this.completeJob(\n activeJob,\n outcome.value ?? undefined,\n );\n break;\n case \"threw\":\n activeJob.ack = this.failJob(\n activeJob,\n outcome.error instanceof Error\n ? outcome.error.message\n : String(outcome.error),\n );\n break;\n case \"timeout\":\n // Stop the handler if it listens, then fail the job: extending the\n // lease of a hung handler forever would keep the job and its\n // concurrency slot stuck.\n abortController.abort(new Error(JOB_TIMEOUT_MESSAGE));\n this.emit(\"job:timeout\", {\n jobId: job.id,\n queueName: job.queueName,\n });\n activeJob.ack = this.failJob(activeJob, JOB_TIMEOUT_MESSAGE);\n break;\n }\n await activeJob.ack;\n } finally {\n this.cleanupJob(activeJob);\n }\n }\n\n /**\n * Run the handler, racing it against the job's `timeoutSeconds`.\n * Never rejects: a throw (sync or async) is reported as an outcome.\n */\n private runHandler(\n activeJob: ActiveJob,\n context: JobContext,\n ): Promise<HandlerOutcome> {\n const run = (async (): Promise<HandlerOutcome> => {\n try {\n return { kind: \"returned\", value: await this.handler!(context) };\n } catch (error) {\n return { kind: \"threw\", error };\n }\n })();\n\n const { timeoutSeconds } = activeJob.job;\n if (typeof timeoutSeconds !== \"number\" || !(timeoutSeconds > 0)) {\n return run;\n }\n\n return new Promise<HandlerOutcome>((resolve) => {\n activeJob.timeoutTimer = setTimeout(\n () => resolve({ kind: \"timeout\" }),\n Math.min(timeoutSeconds * 1000, MAX_TIMER_MS),\n );\n run.then((outcome) => {\n this.clearTimeoutTimer(activeJob);\n resolve(outcome);\n });\n });\n }\n\n /** Abort a handler that outlived the shutdown grace period and fail its job. */\n private async abandonJob(activeJob: ActiveJob): Promise<void> {\n this.debug(`Force-failing job ${activeJob.job.id} due to shutdown timeout`);\n // Mark first: the handler may react to the abort, or finish later, and its\n // outcome must not be acked on top of this failure.\n activeJob.settled = true;\n activeJob.abortController.abort(new Error(SHUTDOWN_TIMEOUT_MESSAGE));\n activeJob.ack = this.failJob(activeJob, SHUTDOWN_TIMEOUT_MESSAGE);\n await activeJob.ack;\n // The handler's finally may never run if user code ignores the abort\n // signal, so explicitly clear this exact execution's timers.\n this.cleanupJob(activeJob);\n }\n\n private async completeJob(\n activeJob: ActiveJob,\n result?: JsonValue,\n ): Promise<void> {\n if (!this.workerId || activeJob.leaseLost) return;\n const { job } = activeJob;\n\n try {\n await this.client.jobs.complete(job.id, {\n workerId: this.workerId,\n result,\n ...(job.leaseId != null && { leaseId: job.leaseId }),\n });\n\n this.emit(\"job:completed\", {\n jobId: job.id,\n queueName: job.queueName,\n result,\n });\n } catch (error) {\n // The lease was reclaimed between the handler returning and the ack.\n // The result belongs to whoever holds the job now; this is not a\n // worker failure.\n if (isLeaseExpired(error)) {\n this.noteLeaseLost(activeJob, error);\n return;\n }\n // The ack was already retried by the HTTP layer; what is left is a job\n // that finished but could not be reported.\n this.debug(`Failed to complete job ${job.id}`, error);\n this.emit(\"error\", { error: error as Error });\n }\n }\n\n private async failJob(\n activeJob: ActiveJob,\n errorMessage: string,\n ): Promise<void> {\n if (!this.workerId || activeJob.leaseLost) return;\n const { job } = activeJob;\n\n const willRetry = job.retryCount < job.maxRetries;\n // The API rejects empty or over-long failure text with a 400, which would\n // leave the job processing until its lease expired.\n const message = coerceFailureMessage(errorMessage);\n\n try {\n await this.client.jobs.fail(job.id, {\n workerId: this.workerId,\n error: message,\n ...(job.leaseId != null && { leaseId: job.leaseId }),\n });\n\n this.emit(\"job:failed\", {\n jobId: job.id,\n queueName: job.queueName,\n error: message,\n willRetry,\n });\n } catch (error) {\n if (isLeaseExpired(error)) {\n this.noteLeaseLost(activeJob, error);\n return;\n }\n this.debug(`Failed to fail job ${job.id}`, error);\n this.emit(\"error\", { error: error as Error });\n }\n }\n\n private clearTimeoutTimer(activeJob: ActiveJob): void {\n if (activeJob.timeoutTimer) {\n clearTimeout(activeJob.timeoutTimer);\n activeJob.timeoutTimer = undefined;\n }\n }\n\n private cleanupJob(activeJob: ActiveJob): void {\n if (activeJob.heartbeatTimer) {\n clearInterval(activeJob.heartbeatTimer);\n activeJob.heartbeatTimer = undefined;\n }\n this.clearTimeoutTimer(activeJob);\n\n if (this.activeJobs.get(activeJob.executionId) === activeJob) {\n this.activeJobs.delete(activeJob.executionId);\n if (this.activeJobs.size === 0) {\n this.drainWaiter?.();\n }\n }\n }\n\n private async sendJobHeartbeat(activeJob: ActiveJob): Promise<void> {\n if (!this.workerId || activeJob.leaseLost) return;\n\n const { job } = activeJob;\n\n try {\n await this.client.jobs.heartbeat(job.id, {\n workerId: this.workerId,\n leaseDurationSecs: this.options.leaseDuration,\n ...(job.leaseId != null && { leaseId: job.leaseId }),\n });\n } catch (error) {\n // 409 LEASE_EXPIRED means this worker no longer holds the job: the\n // lease timed out, or the lease_id does not match. The scheduler has\n // already made the job claimable again, so the handler has to stop\n // and this execution must not ack it. Any other failure is only\n // logged; the next beat may still renew the lease in time.\n if (isLeaseExpired(error)) {\n this.noteLeaseLost(activeJob, error);\n return;\n }\n this.debug(`Job heartbeat failed for ${job.id}`, error);\n }\n }\n\n /**\n * The lease is gone. Abort the handler if it listens, stop renewing, and\n * refuse a later complete/fail with the stale lease.\n */\n private noteLeaseLost(activeJob: ActiveJob, error: unknown): void {\n if (activeJob.leaseLost) return;\n activeJob.leaseLost = true;\n if (activeJob.heartbeatTimer) {\n clearInterval(activeJob.heartbeatTimer);\n activeJob.heartbeatTimer = undefined;\n }\n // A timeout must not fail the job after the lease has been reclaimed.\n this.clearTimeoutTimer(activeJob);\n const reason =\n error instanceof Error ? error : new Error(\"Job lease expired\");\n activeJob.abortController.abort(reason);\n this.debug(\n `Job lease lost for ${activeJob.job.id}; stopping handler`,\n error,\n );\n // Free the slot now. The abort is only a hint: a handler that ignores it\n // (or whose I/O never returns) would otherwise hold a concurrency slot\n // forever, since the timeout above no longer settles it. Its late result\n // is dropped by the leaseLost check in executeHandler.\n activeJob.settled = true;\n this.cleanupJob(activeJob);\n }\n\n private async sendWorkerHeartbeat(): Promise<void> {\n // Keep beating through the shutdown drain: a long `shutdownTimeout` would\n // otherwise let the stale-worker reaper take the worker (and its jobs).\n if (\n !this.workerId ||\n (this.state !== \"running\" && this.state !== \"stopping\")\n ) {\n return;\n }\n\n try {\n await this.client.workers.heartbeat(this.workerId, {\n currentJobs: this.activeJobs.size,\n status: \"healthy\",\n });\n } catch (error) {\n this.debug(\"Worker heartbeat failed\", error);\n }\n }\n\n /**\n * Resolve once no job is active, or after `timeoutMs`. The timer is always\n * cleared, so a clean stop leaves nothing that keeps the process alive.\n */\n private waitForDrain(timeoutMs: number): Promise<void> {\n if (this.activeJobs.size === 0) {\n return Promise.resolve();\n }\n return new Promise<void>((resolve) => {\n const timer = setTimeout(() => {\n this.drainWaiter = null;\n resolve();\n }, timeoutMs);\n this.drainWaiter = () => {\n clearTimeout(timer);\n this.drainWaiter = null;\n resolve();\n };\n });\n }\n}\n\n/**\n * Heartbeat, complete and fail all answer a lost or mismatched lease with\n * 409 `LEASE_EXPIRED` (a mismatch uses that same code). Anything else — a\n * dropped connection, a 5xx — may still succeed on the next beat, so it must\n * not abort the handler.\n */\nfunction isLeaseExpired(error: unknown): boolean {\n return (\n error instanceof SpooledError &&\n error.statusCode === 409 &&\n error.code.toUpperCase() === \"LEASE_EXPIRED\"\n );\n}\n"]}