@rendobar/sdk 4.2.0 → 5.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.
package/README.md CHANGED
@@ -253,14 +253,14 @@ const endpoint = await client.webhooks.create({
253
253
  subscribedEvents: ["job.completed", "job.failed"],
254
254
  });
255
255
 
256
- // Verify signature in your webhook handler
257
- import { verifyWebhookSignature } from "@rendobar/sdk/webhooks";
258
-
259
- const isValid = await verifyWebhookSignature(
260
- requestBody,
261
- request.headers.get("X-Rendobar-Signature"),
262
- signingSecret,
263
- );
256
+ // Verify a delivery in your webhook handler. Pass the raw body (a string, not
257
+ // parsed JSON) and the request headers. verifyWebhook reads the signature and
258
+ // timestamp headers, rebuilds the signed string, checks the HMAC, rejects stale
259
+ // deliveries (replay protection), and handles secret rotation.
260
+ import { verifyWebhook } from "@rendobar/sdk/webhooks";
261
+
262
+ const ok = await verifyWebhook(rawBody, request.headers, signingSecret);
263
+ if (!ok) throw new Error("invalid signature");
264
264
  ```
265
265
 
266
266
  ## Realtime Events (WebSocket)
package/dist/index.cjs CHANGED
@@ -176,7 +176,7 @@ function isAbortError(error) {
176
176
  }
177
177
  //#endregion
178
178
  //#region src/resources/jobs.ts
179
- const TERMINAL_STATUSES$1 = /* @__PURE__ */ new Set([
179
+ const TERMINAL_JOB_STATUSES$1 = /* @__PURE__ */ new Set([
180
180
  "complete",
181
181
  "failed",
182
182
  "cancelled"
@@ -190,7 +190,7 @@ function createJobsResource(request) {
190
190
  if (signal?.aborted) throw new DOMException("Wait aborted", "AbortError");
191
191
  const job = await request(`/jobs/${id}`, { signal });
192
192
  onProgress?.(job);
193
- if (TERMINAL_STATUSES$1.has(job.status)) return resolveTerminal(id, job, throwOnFailure);
193
+ if (TERMINAL_JOB_STATUSES$1.has(job.status)) return resolveTerminal(id, job, throwOnFailure);
194
194
  const remaining = deadline - Date.now();
195
195
  const delay = Math.min(currentInterval, remaining);
196
196
  if (delay <= 0) break;
@@ -199,7 +199,7 @@ function createJobsResource(request) {
199
199
  }
200
200
  const job = await request(`/jobs/${id}`, { signal });
201
201
  onProgress?.(job);
202
- if (TERMINAL_STATUSES$1.has(job.status)) return resolveTerminal(id, job, throwOnFailure);
202
+ if (TERMINAL_JOB_STATUSES$1.has(job.status)) return resolveTerminal(id, job, throwOnFailure);
203
203
  throw new WaitTimeoutError(id, job.status, timeout);
204
204
  }
205
205
  async function create(params, options) {
@@ -762,7 +762,7 @@ const WS_OPTIONS = {
762
762
  reconnectionDelayGrowFactor: 1.5,
763
763
  maxRetries: Infinity
764
764
  };
765
- const TERMINAL_STATUSES = /* @__PURE__ */ new Set([
765
+ const TERMINAL_JOB_STATUSES = /* @__PURE__ */ new Set([
766
766
  "complete",
767
767
  "failed",
768
768
  "cancelled"
@@ -775,8 +775,10 @@ const KNOWN_EVENT_TYPES = /* @__PURE__ */ new Set([
775
775
  "job.progress",
776
776
  "job.step",
777
777
  "job.log",
778
+ "job.resources",
778
779
  "job.metrics",
779
780
  "job.context",
781
+ "job.region_failover",
780
782
  "balance.updated",
781
783
  "subscription.updated",
782
784
  "notification",
@@ -859,15 +861,19 @@ function dispatchJobEvent(event, options) {
859
861
  case "job.status": {
860
862
  const statusEvent = event;
861
863
  options.onStatus?.(statusEvent);
862
- if (TERMINAL_STATUSES.has(statusEvent.status)) options.onComplete?.(statusEvent);
864
+ if (TERMINAL_JOB_STATUSES.has(statusEvent.status)) options.onComplete?.(statusEvent);
863
865
  break;
864
866
  }
865
867
  case "job.result":
866
868
  options.onResult?.(event);
867
869
  break;
868
- case "job.metrics":
869
- options.onMetrics?.(event);
870
+ case "job.resources":
871
+ case "job.metrics": {
872
+ const e = event;
873
+ options.onResources?.(e);
874
+ options.onMetrics?.(e);
870
875
  break;
876
+ }
871
877
  case "job.context":
872
878
  options.onContext?.(event);
873
879
  break;
package/dist/index.d.cts CHANGED
@@ -2246,6 +2246,11 @@ declare const jobErrorSchema: ZodObject<{
2246
2246
  message: ZodString;
2247
2247
  detail: ZodNullable<ZodString>;
2248
2248
  retryable: ZodBoolean;
2249
+ failedPhase: ZodOptional<ZodEnum<{
2250
+ preparing: "preparing";
2251
+ processing: "processing";
2252
+ finalizing: "finalizing";
2253
+ }>>;
2249
2254
  }, $strip>;
2250
2255
  declare const jobCostSchema: ZodObject<{
2251
2256
  amount: ZodNumber;
@@ -2287,7 +2292,8 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2287
2292
  error: ZodOptional<ZodString>;
2288
2293
  }, $strip>>;
2289
2294
  logsAvailable: ZodBoolean;
2290
- metricsAvailable: ZodBoolean;
2295
+ resourcesAvailable: ZodBoolean;
2296
+ metricsAvailable: ZodOptional<ZodBoolean>;
2291
2297
  region: ZodOptional<ZodNullable<ZodString>>;
2292
2298
  createdAt: ZodNumber;
2293
2299
  dispatchedAt: ZodNullable<ZodNumber>;
@@ -2295,6 +2301,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2295
2301
  completedAt: ZodNullable<ZodNumber>;
2296
2302
  settledAt: ZodNullable<ZodNumber>;
2297
2303
  retentionExpiresAt: ZodNullable<ZodNumber>;
2304
+ callback: ZodOptional<ZodNullable<ZodObject<{
2305
+ status: ZodEnum<{
2306
+ pending: "pending";
2307
+ delivered: "delivered";
2308
+ failed: "failed";
2309
+ }>;
2310
+ }, $strip>>>;
2298
2311
  status: ZodLiteral<"waiting">;
2299
2312
  }, $strip>, ZodObject<{
2300
2313
  id: ZodString;
@@ -2331,7 +2344,8 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2331
2344
  error: ZodOptional<ZodString>;
2332
2345
  }, $strip>>;
2333
2346
  logsAvailable: ZodBoolean;
2334
- metricsAvailable: ZodBoolean;
2347
+ resourcesAvailable: ZodBoolean;
2348
+ metricsAvailable: ZodOptional<ZodBoolean>;
2335
2349
  region: ZodOptional<ZodNullable<ZodString>>;
2336
2350
  createdAt: ZodNumber;
2337
2351
  dispatchedAt: ZodNullable<ZodNumber>;
@@ -2339,8 +2353,15 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2339
2353
  completedAt: ZodNullable<ZodNumber>;
2340
2354
  settledAt: ZodNullable<ZodNumber>;
2341
2355
  retentionExpiresAt: ZodNullable<ZodNumber>;
2356
+ callback: ZodOptional<ZodNullable<ZodObject<{
2357
+ status: ZodEnum<{
2358
+ pending: "pending";
2359
+ delivered: "delivered";
2360
+ failed: "failed";
2361
+ }>;
2362
+ }, $strip>>>;
2342
2363
  status: ZodLiteral<"dispatched">;
2343
- progress: ZodOptional<ZodNumber>;
2364
+ progress: ZodOptional<ZodNullable<ZodNumber>>;
2344
2365
  eta: ZodOptional<ZodNullable<ZodNumber>>;
2345
2366
  }, $strip>, ZodObject<{
2346
2367
  id: ZodString;
@@ -2377,7 +2398,8 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2377
2398
  error: ZodOptional<ZodString>;
2378
2399
  }, $strip>>;
2379
2400
  logsAvailable: ZodBoolean;
2380
- metricsAvailable: ZodBoolean;
2401
+ resourcesAvailable: ZodBoolean;
2402
+ metricsAvailable: ZodOptional<ZodBoolean>;
2381
2403
  region: ZodOptional<ZodNullable<ZodString>>;
2382
2404
  createdAt: ZodNumber;
2383
2405
  dispatchedAt: ZodNullable<ZodNumber>;
@@ -2385,8 +2407,15 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2385
2407
  completedAt: ZodNullable<ZodNumber>;
2386
2408
  settledAt: ZodNullable<ZodNumber>;
2387
2409
  retentionExpiresAt: ZodNullable<ZodNumber>;
2410
+ callback: ZodOptional<ZodNullable<ZodObject<{
2411
+ status: ZodEnum<{
2412
+ pending: "pending";
2413
+ delivered: "delivered";
2414
+ failed: "failed";
2415
+ }>;
2416
+ }, $strip>>>;
2388
2417
  status: ZodLiteral<"running">;
2389
- progress: ZodNumber;
2418
+ progress: ZodNullable<ZodNumber>;
2390
2419
  eta: ZodNullable<ZodNumber>;
2391
2420
  }, $strip>, ZodObject<{
2392
2421
  id: ZodString;
@@ -2423,7 +2452,8 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2423
2452
  error: ZodOptional<ZodString>;
2424
2453
  }, $strip>>;
2425
2454
  logsAvailable: ZodBoolean;
2426
- metricsAvailable: ZodBoolean;
2455
+ resourcesAvailable: ZodBoolean;
2456
+ metricsAvailable: ZodOptional<ZodBoolean>;
2427
2457
  region: ZodOptional<ZodNullable<ZodString>>;
2428
2458
  createdAt: ZodNumber;
2429
2459
  dispatchedAt: ZodNullable<ZodNumber>;
@@ -2431,6 +2461,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2431
2461
  completedAt: ZodNullable<ZodNumber>;
2432
2462
  settledAt: ZodNullable<ZodNumber>;
2433
2463
  retentionExpiresAt: ZodNullable<ZodNumber>;
2464
+ callback: ZodOptional<ZodNullable<ZodObject<{
2465
+ status: ZodEnum<{
2466
+ pending: "pending";
2467
+ delivered: "delivered";
2468
+ failed: "failed";
2469
+ }>;
2470
+ }, $strip>>>;
2434
2471
  status: ZodLiteral<"complete">;
2435
2472
  output: ZodObject<{
2436
2473
  data: ZodUnknown;
@@ -2511,7 +2548,8 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2511
2548
  error: ZodOptional<ZodString>;
2512
2549
  }, $strip>>;
2513
2550
  logsAvailable: ZodBoolean;
2514
- metricsAvailable: ZodBoolean;
2551
+ resourcesAvailable: ZodBoolean;
2552
+ metricsAvailable: ZodOptional<ZodBoolean>;
2515
2553
  region: ZodOptional<ZodNullable<ZodString>>;
2516
2554
  createdAt: ZodNumber;
2517
2555
  dispatchedAt: ZodNullable<ZodNumber>;
@@ -2519,12 +2557,24 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2519
2557
  completedAt: ZodNullable<ZodNumber>;
2520
2558
  settledAt: ZodNullable<ZodNumber>;
2521
2559
  retentionExpiresAt: ZodNullable<ZodNumber>;
2560
+ callback: ZodOptional<ZodNullable<ZodObject<{
2561
+ status: ZodEnum<{
2562
+ pending: "pending";
2563
+ delivered: "delivered";
2564
+ failed: "failed";
2565
+ }>;
2566
+ }, $strip>>>;
2522
2567
  status: ZodLiteral<"failed">;
2523
2568
  error: ZodObject<{
2524
2569
  code: ZodString;
2525
2570
  message: ZodString;
2526
2571
  detail: ZodNullable<ZodString>;
2527
2572
  retryable: ZodBoolean;
2573
+ failedPhase: ZodOptional<ZodEnum<{
2574
+ preparing: "preparing";
2575
+ processing: "processing";
2576
+ finalizing: "finalizing";
2577
+ }>>;
2528
2578
  }, $strip>;
2529
2579
  }, $strip>, ZodObject<{
2530
2580
  id: ZodString;
@@ -2561,7 +2611,8 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2561
2611
  error: ZodOptional<ZodString>;
2562
2612
  }, $strip>>;
2563
2613
  logsAvailable: ZodBoolean;
2564
- metricsAvailable: ZodBoolean;
2614
+ resourcesAvailable: ZodBoolean;
2615
+ metricsAvailable: ZodOptional<ZodBoolean>;
2565
2616
  region: ZodOptional<ZodNullable<ZodString>>;
2566
2617
  createdAt: ZodNumber;
2567
2618
  dispatchedAt: ZodNullable<ZodNumber>;
@@ -2569,6 +2620,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2569
2620
  completedAt: ZodNullable<ZodNumber>;
2570
2621
  settledAt: ZodNullable<ZodNumber>;
2571
2622
  retentionExpiresAt: ZodNullable<ZodNumber>;
2623
+ callback: ZodOptional<ZodNullable<ZodObject<{
2624
+ status: ZodEnum<{
2625
+ pending: "pending";
2626
+ delivered: "delivered";
2627
+ failed: "failed";
2628
+ }>;
2629
+ }, $strip>>>;
2572
2630
  status: ZodLiteral<"cancelled">;
2573
2631
  }, $strip>], "status">;
2574
2632
  declare const jobCreatedResponseSchema: ZodObject<{
@@ -2706,10 +2764,10 @@ declare const webhookDeliverySchema: ZodObject<{
2706
2764
  event: ZodString;
2707
2765
  payload: ZodString;
2708
2766
  status: ZodEnum<{
2709
- failed: "failed";
2710
- cancelled: "cancelled";
2711
2767
  pending: "pending";
2712
2768
  delivered: "delivered";
2769
+ failed: "failed";
2770
+ cancelled: "cancelled";
2713
2771
  }>;
2714
2772
  statusCode: ZodNullable<ZodNumber>;
2715
2773
  responseBody: ZodNullable<ZodString>;
@@ -2964,14 +3022,35 @@ declare const orgEventSchema: ZodDiscriminatedUnion<[ZodObject<{
2964
3022
  type: ZodLiteral<"job.progress">;
2965
3023
  jobId: ZodString;
2966
3024
  timestamp: ZodNumber;
2967
- progress: ZodNumber;
3025
+ progress: ZodNullable<ZodNumber>;
3026
+ phase: ZodOptional<ZodEnum<{
3027
+ preparing: "preparing";
3028
+ processing: "processing";
3029
+ finalizing: "finalizing";
3030
+ }>>;
2968
3031
  step: ZodString;
2969
3032
  stepProgress: ZodOptional<ZodNumber>;
2970
3033
  eta: ZodOptional<ZodNumber>;
2971
3034
  metrics: ZodOptional<ZodRecord<ZodString, ZodUnion<readonly [ZodNumber, ZodString]>>>;
2972
3035
  }, $strip>, ZodObject<{
2973
- type: ZodLiteral<"job.metrics">;
3036
+ timestamp: ZodNumber;
3037
+ cpuPct: ZodNumber;
3038
+ cpuCores: ZodNumber;
3039
+ allocatedCores: ZodOptional<ZodNumber>;
3040
+ memUsedMB: ZodNumber;
3041
+ memLimitMB: ZodNumber;
3042
+ diskRMBps: ZodOptional<ZodNumber>;
3043
+ diskWMBps: ZodOptional<ZodNumber>;
3044
+ netRxMBps: ZodOptional<ZodNumber>;
3045
+ netTxMBps: ZodOptional<ZodNumber>;
3046
+ gpuPct: ZodOptional<ZodNumber>;
3047
+ gpuMemUsedMB: ZodOptional<ZodNumber>;
3048
+ gpuMemTotalMB: ZodOptional<ZodNumber>;
3049
+ gpuTempC: ZodOptional<ZodNumber>;
3050
+ gpuPowerW: ZodOptional<ZodNumber>;
3051
+ type: ZodLiteral<"job.resources">;
2974
3052
  jobId: ZodString;
3053
+ }, $strip>, ZodObject<{
2975
3054
  timestamp: ZodNumber;
2976
3055
  cpuPct: ZodNumber;
2977
3056
  cpuCores: ZodNumber;
@@ -2982,6 +3061,13 @@ declare const orgEventSchema: ZodDiscriminatedUnion<[ZodObject<{
2982
3061
  diskWMBps: ZodOptional<ZodNumber>;
2983
3062
  netRxMBps: ZodOptional<ZodNumber>;
2984
3063
  netTxMBps: ZodOptional<ZodNumber>;
3064
+ gpuPct: ZodOptional<ZodNumber>;
3065
+ gpuMemUsedMB: ZodOptional<ZodNumber>;
3066
+ gpuMemTotalMB: ZodOptional<ZodNumber>;
3067
+ gpuTempC: ZodOptional<ZodNumber>;
3068
+ gpuPowerW: ZodOptional<ZodNumber>;
3069
+ type: ZodLiteral<"job.metrics">;
3070
+ jobId: ZodString;
2985
3071
  }, $strip>, ZodObject<{
2986
3072
  type: ZodLiteral<"job.step">;
2987
3073
  jobId: ZodString;
@@ -3518,9 +3604,19 @@ interface RealtimeConnection {
3518
3604
  disconnect: () => void;
3519
3605
  }
3520
3606
  interface JobSubscribeOptions {
3607
+ /**
3608
+ * Overall progress. Build your UI on `event.phase` (stable: preparing |
3609
+ * processing | finalizing) and `event.progress`. `event.step` is the internal
3610
+ * step id — implementation detail, prefer `phase`.
3611
+ */
3521
3612
  onProgress?: (event: Extract<OrgEvent, {
3522
3613
  type: "job.progress";
3523
3614
  }>) => void;
3615
+ /**
3616
+ * @deprecated Internal step transitions leak pipeline detail and vary by job
3617
+ * type. Use `onProgress` (it carries `phase`, and `step` when you need it).
3618
+ * Kept for the dashboard Trace/debug view; not recommended for app UIs.
3619
+ */
3524
3620
  onStep?: (event: Extract<OrgEvent, {
3525
3621
  type: "job.step";
3526
3622
  }>) => void;
@@ -3536,8 +3632,14 @@ interface JobSubscribeOptions {
3536
3632
  onComplete?: (event: Extract<OrgEvent, {
3537
3633
  type: "job.status";
3538
3634
  }>) => void;
3635
+ /** Container resource utilization (CPU, memory, disk, network, GPU). */
3636
+ onResources?: (event: Extract<OrgEvent, {
3637
+ type: "job.resources";
3638
+ }>) => void;
3639
+ /** @deprecated renamed to onResources. Still fires for both event names.
3640
+ * Remove at the next SDK major — tracked in docs/DEPRECATIONS.md (Group A). */
3539
3641
  onMetrics?: (event: Extract<OrgEvent, {
3540
- type: "job.metrics";
3642
+ type: "job.resources";
3541
3643
  }>) => void;
3542
3644
  onContext?: (event: Extract<OrgEvent, {
3543
3645
  type: "job.context";
@@ -3583,6 +3685,31 @@ type CreateJobParams = {
3583
3685
  params?: Record<string, unknown>;
3584
3686
  idempotencyKey?: string;
3585
3687
  forceAsync?: boolean;
3688
+ /**
3689
+ * Per-job completion callback. On a terminal state (complete/failed/cancelled)
3690
+ * Rendobar POSTs the standard job envelope to `url`. HTTPS only. The URL is the
3691
+ * capability — keep it secret, or use the callback as a trigger and re-fetch the
3692
+ * job for authoritative data.
3693
+ *
3694
+ * Optional `headers` (e.g. `{ Authorization: "Bearer …" }`) are sent with the
3695
+ * POST, so the callback can hit an authed target directly — for example
3696
+ * Cloudflare's Workflows events endpoint, with no receiver Worker.
3697
+ *
3698
+ * Set `verify: true` to opt into signing: the POST then carries an
3699
+ * `X-Rendobar-Signature` (same HMAC scheme as webhooks). Fetch your org's
3700
+ * callback signing secret once (`GET /orgs/current/callback-secret`) and verify
3701
+ * with `verifyCallback(rawBody, headers, secret)` from `@rendobar/sdk/webhooks`.
3702
+ *
3703
+ * `events` opts into EXTRA non-terminal events. Terminal events
3704
+ * (complete/failed/cancelled) always fire and can't be filtered out, so a
3705
+ * `waitForEvent` can never hang. Today the only opt-in extra is `job.started`.
3706
+ */
3707
+ callback?: {
3708
+ url: string;
3709
+ headers?: Record<string, string>;
3710
+ verify?: boolean;
3711
+ events?: "job.started"[];
3712
+ };
3586
3713
  };
3587
3714
  type ListJobsParams = {
3588
3715
  status?: string;
package/dist/index.d.mts CHANGED
@@ -2246,6 +2246,11 @@ declare const jobErrorSchema: ZodObject<{
2246
2246
  message: ZodString;
2247
2247
  detail: ZodNullable<ZodString>;
2248
2248
  retryable: ZodBoolean;
2249
+ failedPhase: ZodOptional<ZodEnum<{
2250
+ preparing: "preparing";
2251
+ processing: "processing";
2252
+ finalizing: "finalizing";
2253
+ }>>;
2249
2254
  }, $strip>;
2250
2255
  declare const jobCostSchema: ZodObject<{
2251
2256
  amount: ZodNumber;
@@ -2287,7 +2292,8 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2287
2292
  error: ZodOptional<ZodString>;
2288
2293
  }, $strip>>;
2289
2294
  logsAvailable: ZodBoolean;
2290
- metricsAvailable: ZodBoolean;
2295
+ resourcesAvailable: ZodBoolean;
2296
+ metricsAvailable: ZodOptional<ZodBoolean>;
2291
2297
  region: ZodOptional<ZodNullable<ZodString>>;
2292
2298
  createdAt: ZodNumber;
2293
2299
  dispatchedAt: ZodNullable<ZodNumber>;
@@ -2295,6 +2301,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2295
2301
  completedAt: ZodNullable<ZodNumber>;
2296
2302
  settledAt: ZodNullable<ZodNumber>;
2297
2303
  retentionExpiresAt: ZodNullable<ZodNumber>;
2304
+ callback: ZodOptional<ZodNullable<ZodObject<{
2305
+ status: ZodEnum<{
2306
+ pending: "pending";
2307
+ delivered: "delivered";
2308
+ failed: "failed";
2309
+ }>;
2310
+ }, $strip>>>;
2298
2311
  status: ZodLiteral<"waiting">;
2299
2312
  }, $strip>, ZodObject<{
2300
2313
  id: ZodString;
@@ -2331,7 +2344,8 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2331
2344
  error: ZodOptional<ZodString>;
2332
2345
  }, $strip>>;
2333
2346
  logsAvailable: ZodBoolean;
2334
- metricsAvailable: ZodBoolean;
2347
+ resourcesAvailable: ZodBoolean;
2348
+ metricsAvailable: ZodOptional<ZodBoolean>;
2335
2349
  region: ZodOptional<ZodNullable<ZodString>>;
2336
2350
  createdAt: ZodNumber;
2337
2351
  dispatchedAt: ZodNullable<ZodNumber>;
@@ -2339,8 +2353,15 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2339
2353
  completedAt: ZodNullable<ZodNumber>;
2340
2354
  settledAt: ZodNullable<ZodNumber>;
2341
2355
  retentionExpiresAt: ZodNullable<ZodNumber>;
2356
+ callback: ZodOptional<ZodNullable<ZodObject<{
2357
+ status: ZodEnum<{
2358
+ pending: "pending";
2359
+ delivered: "delivered";
2360
+ failed: "failed";
2361
+ }>;
2362
+ }, $strip>>>;
2342
2363
  status: ZodLiteral<"dispatched">;
2343
- progress: ZodOptional<ZodNumber>;
2364
+ progress: ZodOptional<ZodNullable<ZodNumber>>;
2344
2365
  eta: ZodOptional<ZodNullable<ZodNumber>>;
2345
2366
  }, $strip>, ZodObject<{
2346
2367
  id: ZodString;
@@ -2377,7 +2398,8 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2377
2398
  error: ZodOptional<ZodString>;
2378
2399
  }, $strip>>;
2379
2400
  logsAvailable: ZodBoolean;
2380
- metricsAvailable: ZodBoolean;
2401
+ resourcesAvailable: ZodBoolean;
2402
+ metricsAvailable: ZodOptional<ZodBoolean>;
2381
2403
  region: ZodOptional<ZodNullable<ZodString>>;
2382
2404
  createdAt: ZodNumber;
2383
2405
  dispatchedAt: ZodNullable<ZodNumber>;
@@ -2385,8 +2407,15 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2385
2407
  completedAt: ZodNullable<ZodNumber>;
2386
2408
  settledAt: ZodNullable<ZodNumber>;
2387
2409
  retentionExpiresAt: ZodNullable<ZodNumber>;
2410
+ callback: ZodOptional<ZodNullable<ZodObject<{
2411
+ status: ZodEnum<{
2412
+ pending: "pending";
2413
+ delivered: "delivered";
2414
+ failed: "failed";
2415
+ }>;
2416
+ }, $strip>>>;
2388
2417
  status: ZodLiteral<"running">;
2389
- progress: ZodNumber;
2418
+ progress: ZodNullable<ZodNumber>;
2390
2419
  eta: ZodNullable<ZodNumber>;
2391
2420
  }, $strip>, ZodObject<{
2392
2421
  id: ZodString;
@@ -2423,7 +2452,8 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2423
2452
  error: ZodOptional<ZodString>;
2424
2453
  }, $strip>>;
2425
2454
  logsAvailable: ZodBoolean;
2426
- metricsAvailable: ZodBoolean;
2455
+ resourcesAvailable: ZodBoolean;
2456
+ metricsAvailable: ZodOptional<ZodBoolean>;
2427
2457
  region: ZodOptional<ZodNullable<ZodString>>;
2428
2458
  createdAt: ZodNumber;
2429
2459
  dispatchedAt: ZodNullable<ZodNumber>;
@@ -2431,6 +2461,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2431
2461
  completedAt: ZodNullable<ZodNumber>;
2432
2462
  settledAt: ZodNullable<ZodNumber>;
2433
2463
  retentionExpiresAt: ZodNullable<ZodNumber>;
2464
+ callback: ZodOptional<ZodNullable<ZodObject<{
2465
+ status: ZodEnum<{
2466
+ pending: "pending";
2467
+ delivered: "delivered";
2468
+ failed: "failed";
2469
+ }>;
2470
+ }, $strip>>>;
2434
2471
  status: ZodLiteral<"complete">;
2435
2472
  output: ZodObject<{
2436
2473
  data: ZodUnknown;
@@ -2511,7 +2548,8 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2511
2548
  error: ZodOptional<ZodString>;
2512
2549
  }, $strip>>;
2513
2550
  logsAvailable: ZodBoolean;
2514
- metricsAvailable: ZodBoolean;
2551
+ resourcesAvailable: ZodBoolean;
2552
+ metricsAvailable: ZodOptional<ZodBoolean>;
2515
2553
  region: ZodOptional<ZodNullable<ZodString>>;
2516
2554
  createdAt: ZodNumber;
2517
2555
  dispatchedAt: ZodNullable<ZodNumber>;
@@ -2519,12 +2557,24 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2519
2557
  completedAt: ZodNullable<ZodNumber>;
2520
2558
  settledAt: ZodNullable<ZodNumber>;
2521
2559
  retentionExpiresAt: ZodNullable<ZodNumber>;
2560
+ callback: ZodOptional<ZodNullable<ZodObject<{
2561
+ status: ZodEnum<{
2562
+ pending: "pending";
2563
+ delivered: "delivered";
2564
+ failed: "failed";
2565
+ }>;
2566
+ }, $strip>>>;
2522
2567
  status: ZodLiteral<"failed">;
2523
2568
  error: ZodObject<{
2524
2569
  code: ZodString;
2525
2570
  message: ZodString;
2526
2571
  detail: ZodNullable<ZodString>;
2527
2572
  retryable: ZodBoolean;
2573
+ failedPhase: ZodOptional<ZodEnum<{
2574
+ preparing: "preparing";
2575
+ processing: "processing";
2576
+ finalizing: "finalizing";
2577
+ }>>;
2528
2578
  }, $strip>;
2529
2579
  }, $strip>, ZodObject<{
2530
2580
  id: ZodString;
@@ -2561,7 +2611,8 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2561
2611
  error: ZodOptional<ZodString>;
2562
2612
  }, $strip>>;
2563
2613
  logsAvailable: ZodBoolean;
2564
- metricsAvailable: ZodBoolean;
2614
+ resourcesAvailable: ZodBoolean;
2615
+ metricsAvailable: ZodOptional<ZodBoolean>;
2565
2616
  region: ZodOptional<ZodNullable<ZodString>>;
2566
2617
  createdAt: ZodNumber;
2567
2618
  dispatchedAt: ZodNullable<ZodNumber>;
@@ -2569,6 +2620,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2569
2620
  completedAt: ZodNullable<ZodNumber>;
2570
2621
  settledAt: ZodNullable<ZodNumber>;
2571
2622
  retentionExpiresAt: ZodNullable<ZodNumber>;
2623
+ callback: ZodOptional<ZodNullable<ZodObject<{
2624
+ status: ZodEnum<{
2625
+ pending: "pending";
2626
+ delivered: "delivered";
2627
+ failed: "failed";
2628
+ }>;
2629
+ }, $strip>>>;
2572
2630
  status: ZodLiteral<"cancelled">;
2573
2631
  }, $strip>], "status">;
2574
2632
  declare const jobCreatedResponseSchema: ZodObject<{
@@ -2706,10 +2764,10 @@ declare const webhookDeliverySchema: ZodObject<{
2706
2764
  event: ZodString;
2707
2765
  payload: ZodString;
2708
2766
  status: ZodEnum<{
2709
- failed: "failed";
2710
- cancelled: "cancelled";
2711
2767
  pending: "pending";
2712
2768
  delivered: "delivered";
2769
+ failed: "failed";
2770
+ cancelled: "cancelled";
2713
2771
  }>;
2714
2772
  statusCode: ZodNullable<ZodNumber>;
2715
2773
  responseBody: ZodNullable<ZodString>;
@@ -2964,14 +3022,35 @@ declare const orgEventSchema: ZodDiscriminatedUnion<[ZodObject<{
2964
3022
  type: ZodLiteral<"job.progress">;
2965
3023
  jobId: ZodString;
2966
3024
  timestamp: ZodNumber;
2967
- progress: ZodNumber;
3025
+ progress: ZodNullable<ZodNumber>;
3026
+ phase: ZodOptional<ZodEnum<{
3027
+ preparing: "preparing";
3028
+ processing: "processing";
3029
+ finalizing: "finalizing";
3030
+ }>>;
2968
3031
  step: ZodString;
2969
3032
  stepProgress: ZodOptional<ZodNumber>;
2970
3033
  eta: ZodOptional<ZodNumber>;
2971
3034
  metrics: ZodOptional<ZodRecord<ZodString, ZodUnion<readonly [ZodNumber, ZodString]>>>;
2972
3035
  }, $strip>, ZodObject<{
2973
- type: ZodLiteral<"job.metrics">;
3036
+ timestamp: ZodNumber;
3037
+ cpuPct: ZodNumber;
3038
+ cpuCores: ZodNumber;
3039
+ allocatedCores: ZodOptional<ZodNumber>;
3040
+ memUsedMB: ZodNumber;
3041
+ memLimitMB: ZodNumber;
3042
+ diskRMBps: ZodOptional<ZodNumber>;
3043
+ diskWMBps: ZodOptional<ZodNumber>;
3044
+ netRxMBps: ZodOptional<ZodNumber>;
3045
+ netTxMBps: ZodOptional<ZodNumber>;
3046
+ gpuPct: ZodOptional<ZodNumber>;
3047
+ gpuMemUsedMB: ZodOptional<ZodNumber>;
3048
+ gpuMemTotalMB: ZodOptional<ZodNumber>;
3049
+ gpuTempC: ZodOptional<ZodNumber>;
3050
+ gpuPowerW: ZodOptional<ZodNumber>;
3051
+ type: ZodLiteral<"job.resources">;
2974
3052
  jobId: ZodString;
3053
+ }, $strip>, ZodObject<{
2975
3054
  timestamp: ZodNumber;
2976
3055
  cpuPct: ZodNumber;
2977
3056
  cpuCores: ZodNumber;
@@ -2982,6 +3061,13 @@ declare const orgEventSchema: ZodDiscriminatedUnion<[ZodObject<{
2982
3061
  diskWMBps: ZodOptional<ZodNumber>;
2983
3062
  netRxMBps: ZodOptional<ZodNumber>;
2984
3063
  netTxMBps: ZodOptional<ZodNumber>;
3064
+ gpuPct: ZodOptional<ZodNumber>;
3065
+ gpuMemUsedMB: ZodOptional<ZodNumber>;
3066
+ gpuMemTotalMB: ZodOptional<ZodNumber>;
3067
+ gpuTempC: ZodOptional<ZodNumber>;
3068
+ gpuPowerW: ZodOptional<ZodNumber>;
3069
+ type: ZodLiteral<"job.metrics">;
3070
+ jobId: ZodString;
2985
3071
  }, $strip>, ZodObject<{
2986
3072
  type: ZodLiteral<"job.step">;
2987
3073
  jobId: ZodString;
@@ -3518,9 +3604,19 @@ interface RealtimeConnection {
3518
3604
  disconnect: () => void;
3519
3605
  }
3520
3606
  interface JobSubscribeOptions {
3607
+ /**
3608
+ * Overall progress. Build your UI on `event.phase` (stable: preparing |
3609
+ * processing | finalizing) and `event.progress`. `event.step` is the internal
3610
+ * step id — implementation detail, prefer `phase`.
3611
+ */
3521
3612
  onProgress?: (event: Extract<OrgEvent, {
3522
3613
  type: "job.progress";
3523
3614
  }>) => void;
3615
+ /**
3616
+ * @deprecated Internal step transitions leak pipeline detail and vary by job
3617
+ * type. Use `onProgress` (it carries `phase`, and `step` when you need it).
3618
+ * Kept for the dashboard Trace/debug view; not recommended for app UIs.
3619
+ */
3524
3620
  onStep?: (event: Extract<OrgEvent, {
3525
3621
  type: "job.step";
3526
3622
  }>) => void;
@@ -3536,8 +3632,14 @@ interface JobSubscribeOptions {
3536
3632
  onComplete?: (event: Extract<OrgEvent, {
3537
3633
  type: "job.status";
3538
3634
  }>) => void;
3635
+ /** Container resource utilization (CPU, memory, disk, network, GPU). */
3636
+ onResources?: (event: Extract<OrgEvent, {
3637
+ type: "job.resources";
3638
+ }>) => void;
3639
+ /** @deprecated renamed to onResources. Still fires for both event names.
3640
+ * Remove at the next SDK major — tracked in docs/DEPRECATIONS.md (Group A). */
3539
3641
  onMetrics?: (event: Extract<OrgEvent, {
3540
- type: "job.metrics";
3642
+ type: "job.resources";
3541
3643
  }>) => void;
3542
3644
  onContext?: (event: Extract<OrgEvent, {
3543
3645
  type: "job.context";
@@ -3583,6 +3685,31 @@ type CreateJobParams = {
3583
3685
  params?: Record<string, unknown>;
3584
3686
  idempotencyKey?: string;
3585
3687
  forceAsync?: boolean;
3688
+ /**
3689
+ * Per-job completion callback. On a terminal state (complete/failed/cancelled)
3690
+ * Rendobar POSTs the standard job envelope to `url`. HTTPS only. The URL is the
3691
+ * capability — keep it secret, or use the callback as a trigger and re-fetch the
3692
+ * job for authoritative data.
3693
+ *
3694
+ * Optional `headers` (e.g. `{ Authorization: "Bearer …" }`) are sent with the
3695
+ * POST, so the callback can hit an authed target directly — for example
3696
+ * Cloudflare's Workflows events endpoint, with no receiver Worker.
3697
+ *
3698
+ * Set `verify: true` to opt into signing: the POST then carries an
3699
+ * `X-Rendobar-Signature` (same HMAC scheme as webhooks). Fetch your org's
3700
+ * callback signing secret once (`GET /orgs/current/callback-secret`) and verify
3701
+ * with `verifyCallback(rawBody, headers, secret)` from `@rendobar/sdk/webhooks`.
3702
+ *
3703
+ * `events` opts into EXTRA non-terminal events. Terminal events
3704
+ * (complete/failed/cancelled) always fire and can't be filtered out, so a
3705
+ * `waitForEvent` can never hang. Today the only opt-in extra is `job.started`.
3706
+ */
3707
+ callback?: {
3708
+ url: string;
3709
+ headers?: Record<string, string>;
3710
+ verify?: boolean;
3711
+ events?: "job.started"[];
3712
+ };
3586
3713
  };
3587
3714
  type ListJobsParams = {
3588
3715
  status?: string;
package/dist/index.mjs CHANGED
@@ -175,7 +175,7 @@ function isAbortError(error) {
175
175
  }
176
176
  //#endregion
177
177
  //#region src/resources/jobs.ts
178
- const TERMINAL_STATUSES$1 = /* @__PURE__ */ new Set([
178
+ const TERMINAL_JOB_STATUSES$1 = /* @__PURE__ */ new Set([
179
179
  "complete",
180
180
  "failed",
181
181
  "cancelled"
@@ -189,7 +189,7 @@ function createJobsResource(request) {
189
189
  if (signal?.aborted) throw new DOMException("Wait aborted", "AbortError");
190
190
  const job = await request(`/jobs/${id}`, { signal });
191
191
  onProgress?.(job);
192
- if (TERMINAL_STATUSES$1.has(job.status)) return resolveTerminal(id, job, throwOnFailure);
192
+ if (TERMINAL_JOB_STATUSES$1.has(job.status)) return resolveTerminal(id, job, throwOnFailure);
193
193
  const remaining = deadline - Date.now();
194
194
  const delay = Math.min(currentInterval, remaining);
195
195
  if (delay <= 0) break;
@@ -198,7 +198,7 @@ function createJobsResource(request) {
198
198
  }
199
199
  const job = await request(`/jobs/${id}`, { signal });
200
200
  onProgress?.(job);
201
- if (TERMINAL_STATUSES$1.has(job.status)) return resolveTerminal(id, job, throwOnFailure);
201
+ if (TERMINAL_JOB_STATUSES$1.has(job.status)) return resolveTerminal(id, job, throwOnFailure);
202
202
  throw new WaitTimeoutError(id, job.status, timeout);
203
203
  }
204
204
  async function create(params, options) {
@@ -761,7 +761,7 @@ const WS_OPTIONS = {
761
761
  reconnectionDelayGrowFactor: 1.5,
762
762
  maxRetries: Infinity
763
763
  };
764
- const TERMINAL_STATUSES = /* @__PURE__ */ new Set([
764
+ const TERMINAL_JOB_STATUSES = /* @__PURE__ */ new Set([
765
765
  "complete",
766
766
  "failed",
767
767
  "cancelled"
@@ -774,8 +774,10 @@ const KNOWN_EVENT_TYPES = /* @__PURE__ */ new Set([
774
774
  "job.progress",
775
775
  "job.step",
776
776
  "job.log",
777
+ "job.resources",
777
778
  "job.metrics",
778
779
  "job.context",
780
+ "job.region_failover",
779
781
  "balance.updated",
780
782
  "subscription.updated",
781
783
  "notification",
@@ -858,15 +860,19 @@ function dispatchJobEvent(event, options) {
858
860
  case "job.status": {
859
861
  const statusEvent = event;
860
862
  options.onStatus?.(statusEvent);
861
- if (TERMINAL_STATUSES.has(statusEvent.status)) options.onComplete?.(statusEvent);
863
+ if (TERMINAL_JOB_STATUSES.has(statusEvent.status)) options.onComplete?.(statusEvent);
862
864
  break;
863
865
  }
864
866
  case "job.result":
865
867
  options.onResult?.(event);
866
868
  break;
867
- case "job.metrics":
868
- options.onMetrics?.(event);
869
+ case "job.resources":
870
+ case "job.metrics": {
871
+ const e = event;
872
+ options.onResources?.(e);
873
+ options.onMetrics?.(e);
869
874
  break;
875
+ }
870
876
  case "job.context":
871
877
  options.onContext?.(event);
872
878
  break;
package/dist/webhooks.cjs CHANGED
@@ -77,5 +77,6 @@ async function verifyWebhookSignature(payload, signature, secret) {
77
77
  return mismatch === 0;
78
78
  }
79
79
  //#endregion
80
+ exports.verifyCallback = verifyWebhook;
80
81
  exports.verifyWebhook = verifyWebhook;
81
82
  exports.verifyWebhookSignature = verifyWebhookSignature;
@@ -40,4 +40,4 @@ declare function verifyWebhook(body: string, headers: WebhookHeaders, secret: st
40
40
  */
41
41
  declare function verifyWebhookSignature(payload: string, signature: string, secret: string): Promise<boolean>;
42
42
  //#endregion
43
- export { type WebhookHeaders, verifyWebhook, verifyWebhookSignature };
43
+ export { type WebhookHeaders, verifyWebhook as verifyCallback, verifyWebhook, verifyWebhookSignature };
@@ -40,4 +40,4 @@ declare function verifyWebhook(body: string, headers: WebhookHeaders, secret: st
40
40
  */
41
41
  declare function verifyWebhookSignature(payload: string, signature: string, secret: string): Promise<boolean>;
42
42
  //#endregion
43
- export { type WebhookHeaders, verifyWebhook, verifyWebhookSignature };
43
+ export { type WebhookHeaders, verifyWebhook as verifyCallback, verifyWebhook, verifyWebhookSignature };
package/dist/webhooks.mjs CHANGED
@@ -76,4 +76,4 @@ async function verifyWebhookSignature(payload, signature, secret) {
76
76
  return mismatch === 0;
77
77
  }
78
78
  //#endregion
79
- export { verifyWebhook, verifyWebhookSignature };
79
+ export { verifyWebhook as verifyCallback, verifyWebhook, verifyWebhookSignature };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rendobar/sdk",
3
- "version": "4.2.0",
3
+ "version": "5.1.0",
4
4
  "type": "module",
5
5
  "description": "TypeScript client for the Rendobar media processing API",
6
6
  "main": "./dist/index.cjs",
@@ -34,7 +34,8 @@
34
34
  "build": "tsdown",
35
35
  "typecheck": "tsc --noEmit",
36
36
  "test": "vitest run",
37
- "test:watch": "vitest"
37
+ "test:watch": "vitest",
38
+ "test:live": "vitest run src/__tests__/live"
38
39
  },
39
40
  "dependencies": {
40
41
  "partysocket": "^1.1.16"