@spooled/sdk 1.0.39 → 1.1.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.
@@ -107,11 +107,11 @@ declare const DEFAULT_CONFIG: {
107
107
  successThreshold: number;
108
108
  timeout: number;
109
109
  };
110
- readonly userAgent: "@spooled/sdk-nodejs/1.0.39";
110
+ readonly userAgent: "@spooled/sdk-nodejs/1.1.0";
111
111
  readonly autoRefreshToken: true;
112
112
  };
113
113
  /** SDK version */
114
- declare const SDK_VERSION = "1.0.39";
114
+ declare const SDK_VERSION = "1.1.0";
115
115
  /** API version prefix */
116
116
  declare const API_VERSION = "v1";
117
117
  /**
@@ -231,7 +231,7 @@ declare function createCircuitBreaker(config: CircuitBreakerConfig): CircuitBrea
231
231
  */
232
232
 
233
233
  /** HTTP methods */
234
- type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
234
+ type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
235
235
  /** Query parameters type */
236
236
  type QueryParams = Record<string, string | number | boolean | undefined>;
237
237
  /** Request options for HTTP client */
@@ -340,23 +340,23 @@ declare class HttpClient {
340
340
  /**
341
341
  * Make a GET request
342
342
  */
343
- get<T>(path: string, options?: Omit<HttpRequestOptions, 'method' | 'body'>): Promise<T>;
343
+ get<T>(path: string, options?: Omit<HttpRequestOptions, "method" | "body">): Promise<T>;
344
344
  /**
345
345
  * Make a POST request
346
346
  */
347
- post<T>(path: string, body?: unknown, options?: Omit<HttpRequestOptions, 'method' | 'body'>): Promise<T>;
347
+ post<T>(path: string, body?: unknown, options?: Omit<HttpRequestOptions, "method" | "body">): Promise<T>;
348
348
  /**
349
349
  * Make a PUT request
350
350
  */
351
- put<T>(path: string, body?: unknown, options?: Omit<HttpRequestOptions, 'method' | 'body'>): Promise<T>;
351
+ put<T>(path: string, body?: unknown, options?: Omit<HttpRequestOptions, "method" | "body">): Promise<T>;
352
352
  /**
353
353
  * Make a PATCH request
354
354
  */
355
- patch<T>(path: string, body?: unknown, options?: Omit<HttpRequestOptions, 'method' | 'body'>): Promise<T>;
355
+ patch<T>(path: string, body?: unknown, options?: Omit<HttpRequestOptions, "method" | "body">): Promise<T>;
356
356
  /**
357
357
  * Make a DELETE request
358
358
  */
359
- delete<T = void>(path: string, options?: Omit<HttpRequestOptions, 'method' | 'body'>): Promise<T>;
359
+ delete<T = void>(path: string, options?: Omit<HttpRequestOptions, "method" | "body">): Promise<T>;
360
360
  }
361
361
  /**
362
362
  * Create an HTTP client instance
@@ -377,7 +377,7 @@ interface LoginParams {
377
377
  interface LoginResponse {
378
378
  accessToken: string;
379
379
  refreshToken: string;
380
- tokenType: 'Bearer';
380
+ tokenType: "Bearer";
381
381
  expiresIn: number;
382
382
  refreshExpiresIn: number;
383
383
  }
@@ -388,7 +388,7 @@ interface RefreshTokenParams {
388
388
  /** Token refresh response */
389
389
  interface RefreshTokenResponse {
390
390
  accessToken: string;
391
- tokenType: 'Bearer';
391
+ tokenType: "Bearer";
392
392
  expiresIn: number;
393
393
  }
394
394
  /** Current user info response */
@@ -484,21 +484,21 @@ interface JsonObject {
484
484
  /** JSON array type */
485
485
  type JsonArray = JsonValue[];
486
486
  /** Job status enum values */
487
- type JobStatus = 'pending' | 'scheduled' | 'processing' | 'completed' | 'failed' | 'deadletter' | 'cancelled';
487
+ type JobStatus = "pending" | "scheduled" | "processing" | "completed" | "failed" | "deadletter" | "cancelled";
488
488
  /** Worker status enum values */
489
- type WorkerStatus = 'healthy' | 'degraded' | 'offline' | 'draining';
489
+ type WorkerStatus = "healthy" | "degraded" | "offline" | "draining";
490
490
  /** Workflow status enum values */
491
- type WorkflowStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
491
+ type WorkflowStatus = "pending" | "running" | "completed" | "failed" | "cancelled";
492
492
  /** Plan tier enum values */
493
- type PlanTier = 'free' | 'starter' | 'pro' | 'enterprise';
493
+ type PlanTier = "free" | "starter" | "pro" | "enterprise";
494
494
  /** Schedule run status */
495
- type ScheduleRunStatus = 'pending' | 'running' | 'completed' | 'failed';
495
+ type ScheduleRunStatus = "pending" | "running" | "completed" | "failed";
496
496
  /** Webhook delivery status */
497
- type WebhookDeliveryStatus = 'pending' | 'success' | 'failed';
497
+ type WebhookDeliveryStatus = "pending" | "success" | "failed";
498
498
  /** Webhook event types */
499
- type WebhookEventType = 'job.created' | 'job.started' | 'job.completed' | 'job.failed' | 'job.cancelled' | 'queue.paused' | 'queue.resumed' | 'worker.registered' | 'worker.deregistered' | 'schedule.triggered';
499
+ type WebhookEventType = "job.created" | "job.started" | "job.completed" | "job.failed" | "job.cancelled" | "queue.paused" | "queue.resumed" | "worker.registered" | "worker.deregistered" | "schedule.triggered";
500
500
  /** Dependency mode for workflows */
501
- type DependencyMode = 'all' | 'any';
501
+ type DependencyMode = "all" | "any";
502
502
  /** Pagination parameters */
503
503
  interface PaginationParams {
504
504
  /** Maximum number of results */
@@ -511,7 +511,7 @@ interface ListParams extends PaginationParams {
511
511
  /** Field to order by */
512
512
  orderBy?: string;
513
513
  /** Sort direction */
514
- orderDir?: 'asc' | 'desc';
514
+ orderDir?: "asc" | "desc";
515
515
  }
516
516
  /** Paginated response wrapper */
517
517
  interface PaginatedResponse<T> {
@@ -976,15 +976,21 @@ interface Worker {
976
976
  id: string;
977
977
  organizationId: string;
978
978
  queueName: string;
979
+ /** Multi-queue membership when present (detail response). */
980
+ queueNames?: string[];
979
981
  hostname: string;
980
- workerType?: string;
982
+ /** Serialized as explicit null by the backend when not set. */
983
+ workerType?: string | null;
981
984
  maxConcurrency: number;
982
985
  currentJobs: number;
983
986
  status: WorkerStatus;
984
987
  lastHeartbeat: string;
985
988
  metadata: JsonObject;
986
- version?: string;
989
+ /** Serialized as explicit null by the backend when not set. */
990
+ version?: string | null;
987
991
  registeredAt: string;
992
+ /** Last row update (detail response). */
993
+ updatedAt?: string;
988
994
  }
989
995
  /** Worker summary for list responses */
990
996
  interface WorkerSummary {
@@ -1000,6 +1006,18 @@ interface WorkerSummary {
1000
1006
  interface RegisterWorkerParams {
1001
1007
  /** Queue name to process */
1002
1008
  queueName: string;
1009
+ /**
1010
+ * Stable worker identifier (1-128 chars, `[A-Za-z0-9._-]`).
1011
+ *
1012
+ * Supplying one makes registration an upsert, so a restarting worker reuses
1013
+ * a single row and re-registering an id you already own is not charged
1014
+ * against the plan worker cap. Omit it and the server mints a UUID, which
1015
+ * means every restart leaves the old row occupying the cap until the
1016
+ * stale-worker reaper clears it (~2 minutes) — enough for a crash-looping
1017
+ * worker on a tight plan to 429 itself out of registering. An id owned by a
1018
+ * different organization is rejected with HTTP 409.
1019
+ */
1020
+ workerId?: string;
1003
1021
  /** Worker hostname */
1004
1022
  hostname: string;
1005
1023
  /** Worker type identifier */
@@ -1323,7 +1341,7 @@ interface WorkflowJob {
1323
1341
  /** Queue name */
1324
1342
  queueName: string;
1325
1343
  /** Current job status */
1326
- status: 'pending' | 'queued' | 'running' | 'completed' | 'failed' | 'cancelled' | 'deadletter';
1344
+ status: "pending" | "queued" | "running" | "completed" | "failed" | "cancelled" | "deadletter";
1327
1345
  /** Job payload */
1328
1346
  payload: JsonObject;
1329
1347
  /** Job result (if completed) */
@@ -1479,9 +1497,24 @@ interface OutgoingWebhook {
1479
1497
  url: string;
1480
1498
  events: WebhookEventType[];
1481
1499
  enabled: boolean;
1500
+ /**
1501
+ * Consecutive failed deliveries.
1502
+ *
1503
+ * Counted once per DELIVERY, not once per retry attempt, so for the same
1504
+ * real-world failures this is roughly 5x smaller than a per-attempt count.
1505
+ * A successful delivery resets it to 0, including a successful manual retry
1506
+ * via `retryDelivery()`. At 20 the webhook is disabled automatically.
1507
+ */
1482
1508
  failureCount: number;
1483
1509
  lastTriggeredAt?: string;
1484
- lastStatus?: 'success' | 'failed';
1510
+ /**
1511
+ * Outcome of the most recent delivery.
1512
+ *
1513
+ * `"auto_disabled"` means 20 consecutive failed deliveries disabled the
1514
+ * webhook: `enabled` is now false and no further events are delivered until
1515
+ * it is re-enabled with `update(id, { enabled: true })`.
1516
+ */
1517
+ lastStatus?: "success" | "failed" | "auto_disabled";
1485
1518
  createdAt: string;
1486
1519
  updatedAt: string;
1487
1520
  }
@@ -1498,12 +1531,34 @@ interface CreateOutgoingWebhookParams {
1498
1531
  /** Whether enabled (default: true) */
1499
1532
  enabled?: boolean;
1500
1533
  }
1501
- /** Parameters for updating an outgoing webhook */
1534
+ /**
1535
+ * Parameters for updating an outgoing webhook.
1536
+ *
1537
+ * Every field is optional and only the fields you send are changed.
1538
+ */
1502
1539
  interface UpdateOutgoingWebhookParams {
1503
1540
  name?: string;
1504
1541
  url?: string;
1505
1542
  events?: WebhookEventType[];
1506
- secret?: string;
1543
+ /**
1544
+ * HMAC secret used to sign deliveries.
1545
+ *
1546
+ * Omit the field to keep the current secret, pass a string to replace it, or
1547
+ * pass `null` to CLEAR it. Clearing is destructive: deliveries then go out
1548
+ * unsigned, with no `X-Spooled-Signature` header, and the old secret cannot
1549
+ * be recovered. Client code that reserialises an unchanged webhook must send
1550
+ * `undefined` (or drop the key) rather than `null`, or it will wipe a live
1551
+ * secret.
1552
+ */
1553
+ secret?: string | null;
1554
+ /**
1555
+ * Whether the webhook receives events.
1556
+ *
1557
+ * Setting this to `true` is the recovery path for a webhook that was
1558
+ * auto-disabled after 20 consecutive failed deliveries. Re-enabling is
1559
+ * charged against the plan webhook cap, so it can fail with HTTP 429
1560
+ * `QUOTA_EXCEEDED` even though no webhook is being created.
1561
+ */
1507
1562
  enabled?: boolean;
1508
1563
  }
1509
1564
  /** Response for webhook test */
@@ -1513,7 +1568,15 @@ interface TestWebhookResponse {
1513
1568
  responseTimeMs: number;
1514
1569
  error?: string;
1515
1570
  }
1516
- /** Webhook delivery record */
1571
+ /**
1572
+ * Webhook delivery record.
1573
+ *
1574
+ * Delivery history is retained, not permanent: rows are removed by the
1575
+ * per-organization retention sweep using the plan's history retention window
1576
+ * (free 1 day, starter 7, pro 30, enterprise 90). Only the newest 100
1577
+ * deliveries per webhook are readable through the API in any case, so copy
1578
+ * anything you need as a durable audit record into your own store.
1579
+ */
1517
1580
  interface OutgoingWebhookDelivery {
1518
1581
  id: string;
1519
1582
  webhookId: string;
@@ -1587,6 +1650,12 @@ interface ApiKeySummary {
1587
1650
  rateLimit?: number;
1588
1651
  isActive: boolean;
1589
1652
  createdAt: string;
1653
+ /**
1654
+ * Coarse last-use timestamp, written at most once per key per 5 minutes
1655
+ * rather than on every request. Treat it as "used recently", not as a live
1656
+ * signal: it can lag actual use by up to 5 minutes, so it cannot answer
1657
+ * "is this key in use right now" and idle-key checks must allow for the lag.
1658
+ */
1590
1659
  lastUsed?: string;
1591
1660
  expiresAt?: string;
1592
1661
  }
@@ -1756,7 +1825,7 @@ interface UsageItem {
1756
1825
  interface UsageWarning {
1757
1826
  resource: string;
1758
1827
  message: string;
1759
- severity: 'warning' | 'critical' | string;
1828
+ severity: "warning" | "critical" | string;
1760
1829
  }
1761
1830
  /** Organization member */
1762
1831
  interface OrganizationMember {
@@ -2043,7 +2112,7 @@ interface AdminListOrganizationsParams {
2043
2112
  limit?: number;
2044
2113
  offset?: number;
2045
2114
  sortBy?: string;
2046
- sortOrder?: 'asc' | 'desc' | string;
2115
+ sortOrder?: "asc" | "desc" | string;
2047
2116
  }
2048
2117
  interface AdminUsageStats {
2049
2118
  jobsToday: number;
@@ -2193,7 +2262,7 @@ interface IngestGitHubWebhookOptions {
2193
2262
  /** Optional org-scoped webhook token (X-Webhook-Token) */
2194
2263
  webhookToken?: string;
2195
2264
  /** Optional X-Forwarded-Proto override (production servers may require https) */
2196
- forwardedProto?: 'https' | 'http' | string;
2265
+ forwardedProto?: "https" | "http" | string;
2197
2266
  /** Provide a precomputed X-Hub-Signature-256 header value (sha256=<hex>) */
2198
2267
  signature?: string;
2199
2268
  /** If provided, the SDK will compute the signature for you */
@@ -2203,7 +2272,7 @@ interface IngestStripeWebhookOptions {
2203
2272
  /** Optional org-scoped webhook token (X-Webhook-Token) */
2204
2273
  webhookToken?: string;
2205
2274
  /** Optional X-Forwarded-Proto override */
2206
- forwardedProto?: 'https' | 'http' | string;
2275
+ forwardedProto?: "https" | "http" | string;
2207
2276
  /** Provide a precomputed Stripe-Signature header */
2208
2277
  signature?: string;
2209
2278
  /** If provided, the SDK will compute the signature for you */
@@ -2271,7 +2340,7 @@ interface RealtimeEventBase {
2271
2340
  }
2272
2341
  /** Job created event */
2273
2342
  interface JobCreatedEvent extends RealtimeEventBase {
2274
- type: 'job.created';
2343
+ type: "job.created";
2275
2344
  data: {
2276
2345
  jobId: string;
2277
2346
  queueName: string;
@@ -2280,7 +2349,7 @@ interface JobCreatedEvent extends RealtimeEventBase {
2280
2349
  }
2281
2350
  /** Job started event */
2282
2351
  interface JobStartedEvent extends RealtimeEventBase {
2283
- type: 'job.started';
2352
+ type: "job.started";
2284
2353
  data: {
2285
2354
  jobId: string;
2286
2355
  queueName: string;
@@ -2289,7 +2358,7 @@ interface JobStartedEvent extends RealtimeEventBase {
2289
2358
  }
2290
2359
  /** Job completed event */
2291
2360
  interface JobCompletedEvent extends RealtimeEventBase {
2292
- type: 'job.completed';
2361
+ type: "job.completed";
2293
2362
  data: {
2294
2363
  jobId: string;
2295
2364
  queueName: string;
@@ -2299,7 +2368,7 @@ interface JobCompletedEvent extends RealtimeEventBase {
2299
2368
  }
2300
2369
  /** Job failed event */
2301
2370
  interface JobFailedEvent extends RealtimeEventBase {
2302
- type: 'job.failed';
2371
+ type: "job.failed";
2303
2372
  data: {
2304
2373
  jobId: string;
2305
2374
  queueName: string;
@@ -2310,7 +2379,7 @@ interface JobFailedEvent extends RealtimeEventBase {
2310
2379
  }
2311
2380
  /** Job progress event */
2312
2381
  interface JobProgressEvent extends RealtimeEventBase {
2313
- type: 'job.progress';
2382
+ type: "job.progress";
2314
2383
  data: {
2315
2384
  jobId: string;
2316
2385
  queueName: string;
@@ -2320,7 +2389,7 @@ interface JobProgressEvent extends RealtimeEventBase {
2320
2389
  }
2321
2390
  /** Job status changed event */
2322
2391
  interface JobStatusChangedEvent extends RealtimeEventBase {
2323
- type: 'job.status_changed';
2392
+ type: "job.status_changed";
2324
2393
  data: {
2325
2394
  jobId: string;
2326
2395
  queueName: string;
@@ -2330,7 +2399,7 @@ interface JobStatusChangedEvent extends RealtimeEventBase {
2330
2399
  }
2331
2400
  /** Queue stats update event (backend `QueueStats`) */
2332
2401
  interface QueueStatsEvent extends RealtimeEventBase {
2333
- type: 'queue.stats';
2402
+ type: "queue.stats";
2334
2403
  data: {
2335
2404
  queueName: string;
2336
2405
  pending: number;
@@ -2341,7 +2410,7 @@ interface QueueStatsEvent extends RealtimeEventBase {
2341
2410
  }
2342
2411
  /** Worker heartbeat event (backend `WorkerHeartbeat`) */
2343
2412
  interface WorkerHeartbeatEvent extends RealtimeEventBase {
2344
- type: 'worker.heartbeat';
2413
+ type: "worker.heartbeat";
2345
2414
  data: {
2346
2415
  workerId: string;
2347
2416
  status: string;
@@ -2350,7 +2419,7 @@ interface WorkerHeartbeatEvent extends RealtimeEventBase {
2350
2419
  }
2351
2420
  /** Queue paused event */
2352
2421
  interface QueuePausedEvent extends RealtimeEventBase {
2353
- type: 'queue.paused';
2422
+ type: "queue.paused";
2354
2423
  data: {
2355
2424
  queueName: string;
2356
2425
  reason?: string;
@@ -2358,14 +2427,14 @@ interface QueuePausedEvent extends RealtimeEventBase {
2358
2427
  }
2359
2428
  /** Queue resumed event */
2360
2429
  interface QueueResumedEvent extends RealtimeEventBase {
2361
- type: 'queue.resumed';
2430
+ type: "queue.resumed";
2362
2431
  data: {
2363
2432
  queueName: string;
2364
2433
  };
2365
2434
  }
2366
2435
  /** Worker registered event */
2367
2436
  interface WorkerRegisteredEvent extends RealtimeEventBase {
2368
- type: 'worker.registered';
2437
+ type: "worker.registered";
2369
2438
  data: {
2370
2439
  workerId: string;
2371
2440
  queueName: string;
@@ -2374,7 +2443,7 @@ interface WorkerRegisteredEvent extends RealtimeEventBase {
2374
2443
  }
2375
2444
  /** Worker deregistered event */
2376
2445
  interface WorkerDeregisteredEvent extends RealtimeEventBase {
2377
- type: 'worker.deregistered';
2446
+ type: "worker.deregistered";
2378
2447
  data: {
2379
2448
  workerId: string;
2380
2449
  queueName: string;
@@ -2382,7 +2451,7 @@ interface WorkerDeregisteredEvent extends RealtimeEventBase {
2382
2451
  }
2383
2452
  /** Schedule triggered event */
2384
2453
  interface ScheduleTriggeredEvent extends RealtimeEventBase {
2385
- type: 'schedule.triggered';
2454
+ type: "schedule.triggered";
2386
2455
  data: {
2387
2456
  scheduleId: string;
2388
2457
  jobId: string;
@@ -2390,7 +2459,7 @@ interface ScheduleTriggeredEvent extends RealtimeEventBase {
2390
2459
  }
2391
2460
  /** Heartbeat event (for connection keep-alive) */
2392
2461
  interface HeartbeatEvent extends RealtimeEventBase {
2393
- type: 'heartbeat';
2462
+ type: "heartbeat";
2394
2463
  data: {
2395
2464
  serverTime: string;
2396
2465
  };
@@ -2398,13 +2467,13 @@ interface HeartbeatEvent extends RealtimeEventBase {
2398
2467
  /** All realtime event types */
2399
2468
  type RealtimeEvent = JobCreatedEvent | JobStartedEvent | JobCompletedEvent | JobFailedEvent | JobProgressEvent | JobStatusChangedEvent | QueueStatsEvent | QueuePausedEvent | QueueResumedEvent | WorkerRegisteredEvent | WorkerDeregisteredEvent | WorkerHeartbeatEvent | ScheduleTriggeredEvent | HeartbeatEvent;
2400
2469
  /** Event type names */
2401
- type RealtimeEventType = RealtimeEvent['type'];
2470
+ type RealtimeEventType = RealtimeEvent["type"];
2402
2471
  /** Extract event data type from event type name */
2403
2472
  type RealtimeEventData<T extends RealtimeEventType> = Extract<RealtimeEvent, {
2404
2473
  type: T;
2405
- }>['data'];
2474
+ }>["data"];
2406
2475
  /** Connection state */
2407
- type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting';
2476
+ type ConnectionState = "disconnected" | "connecting" | "connected" | "reconnecting";
2408
2477
  /** Realtime connection options */
2409
2478
  interface RealtimeConnectionOptions {
2410
2479
  /** Base URL for the REST API (e.g., https://api.spooled.cloud) - used for SSE */
@@ -2452,7 +2521,7 @@ interface SpooledRealtimeOptions {
2452
2521
  * - WebSocket uses push/pubsub in the backend
2453
2522
  * - SSE job/queue endpoints poll the database periodically
2454
2523
  */
2455
- type?: 'websocket' | 'sse';
2524
+ type?: "websocket" | "sse";
2456
2525
  /** Auto-reconnect on disconnect (default: true) */
2457
2526
  autoReconnect?: boolean;
2458
2527
  /** Maximum reconnect attempts (default: 10) */
@@ -2788,6 +2857,8 @@ interface GrpcClientOptions {
2788
2857
  credentials?: grpc.ChannelCredentials;
2789
2858
  /** Channel options */
2790
2859
  channelOptions?: grpc.ChannelOptions;
2860
+ /** Deadline for unary gRPC calls in milliseconds. Streams are not bounded unless explicitly configured. */
2861
+ timeout?: number;
2791
2862
  }
2792
2863
  /** @deprecated Use GrpcEnqueueRequest */
2793
2864
  type GrpcEnqueueJobParams = GrpcEnqueueRequest & {
@@ -2922,21 +2993,25 @@ declare function createJobStream(call: grpc.ClientReadableStream<GrpcJob>, optio
2922
2993
  */
2923
2994
 
2924
2995
  type UnaryCallback<T> = (error: grpc.ServiceError | null, response: T) => void;
2996
+ type UnaryMethod<TReq, TRes> = {
2997
+ (request: TReq, metadata: grpc.Metadata, callback: UnaryCallback<TRes>): void;
2998
+ (request: TReq, metadata: grpc.Metadata, options: grpc.CallOptions, callback: UnaryCallback<TRes>): void;
2999
+ };
2925
3000
  interface QueueServiceClient extends grpc.Client {
2926
- Enqueue(request: GrpcEnqueueRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcEnqueueResponse>): void;
2927
- Dequeue(request: GrpcDequeueRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcDequeueResponse>): void;
2928
- Complete(request: GrpcCompleteRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcCompleteResponse>): void;
2929
- Fail(request: GrpcFailRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcFailResponse>): void;
2930
- RenewLease(request: GrpcRenewLeaseRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcRenewLeaseResponse>): void;
2931
- GetJob(request: GrpcGetJobRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcGetJobResponse>): void;
2932
- GetQueueStats(request: GrpcGetQueueStatsRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcGetQueueStatsResponse>): void;
3001
+ Enqueue: UnaryMethod<GrpcEnqueueRequest, GrpcEnqueueResponse>;
3002
+ Dequeue: UnaryMethod<GrpcDequeueRequest, GrpcDequeueResponse>;
3003
+ Complete: UnaryMethod<GrpcCompleteRequest, GrpcCompleteResponse>;
3004
+ Fail: UnaryMethod<GrpcFailRequest, GrpcFailResponse>;
3005
+ RenewLease: UnaryMethod<GrpcRenewLeaseRequest, GrpcRenewLeaseResponse>;
3006
+ GetJob: UnaryMethod<GrpcGetJobRequest, GrpcGetJobResponse>;
3007
+ GetQueueStats: UnaryMethod<GrpcGetQueueStatsRequest, GrpcGetQueueStatsResponse>;
2933
3008
  StreamJobs(request: GrpcStreamJobsRequest, metadata: grpc.Metadata): grpc.ClientReadableStream<GrpcJob>;
2934
3009
  ProcessJobs(metadata: grpc.Metadata): grpc.ClientDuplexStream<GrpcProcessRequest, GrpcProcessResponse>;
2935
3010
  }
2936
3011
  interface WorkerServiceClient extends grpc.Client {
2937
- Register(request: GrpcRegisterWorkerRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcRegisterWorkerResponse>): void;
2938
- Heartbeat(request: GrpcHeartbeatRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcHeartbeatResponse>): void;
2939
- Deregister(request: GrpcDeregisterRequest, metadata: grpc.Metadata, callback: UnaryCallback<GrpcDeregisterResponse>): void;
3012
+ Register: UnaryMethod<GrpcRegisterWorkerRequest, GrpcRegisterWorkerResponse>;
3013
+ Heartbeat: UnaryMethod<GrpcHeartbeatRequest, GrpcHeartbeatResponse>;
3014
+ Deregister: UnaryMethod<GrpcDeregisterRequest, GrpcDeregisterResponse>;
2940
3015
  }
2941
3016
  /**
2942
3017
  * Queue operations for the gRPC client
@@ -2944,7 +3019,8 @@ interface WorkerServiceClient extends grpc.Client {
2944
3019
  declare class GrpcQueueOperations {
2945
3020
  private readonly client;
2946
3021
  private readonly metadata;
2947
- constructor(client: QueueServiceClient, metadata: grpc.Metadata);
3022
+ private readonly timeoutMs?;
3023
+ constructor(client: QueueServiceClient, metadata: grpc.Metadata, timeoutMs?: number | undefined);
2948
3024
  /**
2949
3025
  * Enqueue a new job
2950
3026
  */
@@ -3018,7 +3094,8 @@ declare class GrpcQueueOperations {
3018
3094
  declare class GrpcWorkerOperations {
3019
3095
  private readonly client;
3020
3096
  private readonly metadata;
3021
- constructor(client: WorkerServiceClient, metadata: grpc.Metadata);
3097
+ private readonly timeoutMs?;
3098
+ constructor(client: WorkerServiceClient, metadata: grpc.Metadata, timeoutMs?: number | undefined);
3022
3099
  /**
3023
3100
  * Register a new worker
3024
3101
  */
@@ -3278,6 +3355,16 @@ declare function createClient(options: SpooledClientConfig): SpooledClient;
3278
3355
  interface SpooledWorkerOptions {
3279
3356
  /** Queue name to process */
3280
3357
  queueName: string;
3358
+ /**
3359
+ * Stable worker identifier (1-128 chars, `[A-Za-z0-9._-]`).
3360
+ *
3361
+ * Set this on any worker that restarts or redeploys: registration becomes an
3362
+ * upsert, so the process reuses one row instead of leaving the previous
3363
+ * registration to occupy the plan worker cap until the stale-worker reaper
3364
+ * clears it (~2 minutes). Omit it and the server mints a UUID on every
3365
+ * start. An id owned by a different organization is rejected with HTTP 409.
3366
+ */
3367
+ workerId?: string;
3281
3368
  /** Worker hostname (default: auto-detected) */
3282
3369
  hostname?: string;
3283
3370
  /** Worker type identifier */
@@ -3300,7 +3387,7 @@ interface SpooledWorkerOptions {
3300
3387
  shutdownTimeout?: number;
3301
3388
  }
3302
3389
  /** Worker state */
3303
- type WorkerState = 'idle' | 'starting' | 'running' | 'stopping' | 'stopped' | 'error';
3390
+ type WorkerState = "idle" | "starting" | "running" | "stopping" | "stopped" | "error";
3304
3391
  /** Job context passed to handlers */
3305
3392
  interface JobContext {
3306
3393
  /** Job ID */
@@ -3315,10 +3402,10 @@ interface JobContext {
3315
3402
  maxRetries: number;
3316
3403
  /** Abort signal for graceful shutdown */
3317
3404
  signal: AbortSignal;
3318
- /** Update job progress (0-100) */
3405
+ /** Log local job progress (0-100); backend progress persistence is not yet available. */
3319
3406
  progress: (percent: number, message?: string) => Promise<void>;
3320
3407
  /** Log a message */
3321
- log: (level: 'debug' | 'info' | 'warn' | 'error', message: string, meta?: unknown) => void;
3408
+ log: (level: "debug" | "info" | "warn" | "error", message: string, meta?: unknown) => void;
3322
3409
  }
3323
3410
  /** Job handler function */
3324
3411
  type JobHandler = (context: JobContext) => Promise<JsonObject | void>;
@@ -3329,7 +3416,7 @@ interface JobResult {
3329
3416
  error?: string;
3330
3417
  }
3331
3418
  /** Worker event types */
3332
- type WorkerEvent = 'started' | 'stopped' | 'error' | 'job:claimed' | 'job:started' | 'job:completed' | 'job:failed' | 'job:timeout';
3419
+ type WorkerEvent = "started" | "stopped" | "error" | "job:claimed" | "job:started" | "job:completed" | "job:failed" | "job:timeout";
3333
3420
  /** Worker event data types */
3334
3421
  interface WorkerEventData {
3335
3422
  started: {
@@ -3343,26 +3430,26 @@ interface WorkerEventData {
3343
3430
  error: {
3344
3431
  error: Error;
3345
3432
  };
3346
- 'job:claimed': {
3433
+ "job:claimed": {
3347
3434
  jobId: string;
3348
3435
  queueName: string;
3349
3436
  };
3350
- 'job:started': {
3437
+ "job:started": {
3351
3438
  jobId: string;
3352
3439
  queueName: string;
3353
3440
  };
3354
- 'job:completed': {
3441
+ "job:completed": {
3355
3442
  jobId: string;
3356
3443
  queueName: string;
3357
3444
  result?: JsonObject;
3358
3445
  };
3359
- 'job:failed': {
3446
+ "job:failed": {
3360
3447
  jobId: string;
3361
3448
  queueName: string;
3362
3449
  error: string;
3363
3450
  willRetry: boolean;
3364
3451
  };
3365
- 'job:timeout': {
3452
+ "job:timeout": {
3366
3453
  jobId: string;
3367
3454
  queueName: string;
3368
3455
  };
@@ -3408,6 +3495,11 @@ type EventHandler<E extends WorkerEvent> = (data: WorkerEventData[E]) => void;
3408
3495
  */
3409
3496
  declare class SpooledWorker {
3410
3497
  private readonly client;
3498
+ /**
3499
+ * Options with every defaultable field filled in. `workerId` stays optional:
3500
+ * there is no sensible default for it, and omitting it is what makes the
3501
+ * server mint a UUID.
3502
+ */
3411
3503
  private readonly options;
3412
3504
  private readonly debug;
3413
3505
  private state;