@lostgradient/weft 0.12.0 → 0.14.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.
Files changed (226) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/api.d.ts +2 -0
  3. package/dist/cli/api.js +3 -4
  4. package/dist/cli/generated/operation-catalog.snapshot.json +508 -12
  5. package/dist/cli/generated/operation-client.generated.d.ts +118 -10
  6. package/dist/cli/generated/operation-client.generated.js +74 -1
  7. package/dist/cli/help-text.d.ts +3 -3
  8. package/dist/cli/help-text.js +4 -4
  9. package/dist/cli/operation-catalog-snapshot.d.ts +12 -3
  10. package/dist/cli/operation-catalog-snapshot.js +14 -5
  11. package/dist/cli/operation-client-runtime.d.ts +29 -0
  12. package/dist/cli/schedule.js +1 -3
  13. package/dist/cli/serve-registrations.d.ts +3 -3
  14. package/dist/cli/serve-registrations.js +2 -2
  15. package/dist/cli/shutdown.d.ts +11 -0
  16. package/dist/cli/shutdown.js +25 -0
  17. package/dist/cli/validate.d.ts +1 -1
  18. package/dist/cli/version-check.d.ts +1 -1
  19. package/dist/cli/version-check.js +1 -1
  20. package/dist/cli-main.js +10 -29
  21. package/dist/client/client-storage.d.ts +24 -0
  22. package/dist/client/client-storage.js +14 -0
  23. package/dist/client/handle-delegation.d.ts +3 -3
  24. package/dist/client/handle-delegation.js +2 -2
  25. package/dist/client/http-client-requests.d.ts +5 -3
  26. package/dist/client/http-client-requests.js +20 -2
  27. package/dist/client/http-client-storage.d.ts +3 -0
  28. package/dist/client/http-client-storage.js +82 -0
  29. package/dist/client/http-client.d.ts +9 -6
  30. package/dist/client/http-client.js +13 -18
  31. package/dist/client/http-operations.d.ts +3 -1
  32. package/dist/client/http-operations.js +77 -1
  33. package/dist/client/http-request.d.ts +20 -14
  34. package/dist/client/http-request.js +21 -31
  35. package/dist/client/in-process-operations.d.ts +2 -2
  36. package/dist/client/in-process-operations.js +2 -2
  37. package/dist/client/index.d.ts +5 -1
  38. package/dist/client/index.js +13 -2
  39. package/dist/client/interface.d.ts +26 -26
  40. package/dist/client/local.d.ts +9 -6
  41. package/dist/client/local.js +9 -4
  42. package/dist/client/search-params.js +10 -6
  43. package/dist/client/start-body.d.ts +3 -1
  44. package/dist/client/start-body.js +9 -0
  45. package/dist/core/bulk-workflow-filter.d.ts +2 -1
  46. package/dist/core/bulk-workflow-filter.js +5 -1
  47. package/dist/core/context/parallel-operations.d.ts +0 -2
  48. package/dist/core/context/parallel-operations.js +0 -7
  49. package/dist/core/engine/async-activity-records.d.ts +12 -1
  50. package/dist/core/engine/async-activity-records.js +81 -2
  51. package/dist/core/engine/bulk-operations-purge.js +16 -1
  52. package/dist/core/engine/bulk-operations-shared.js +2 -0
  53. package/dist/core/engine/callback-checkpoint-persistence.d.ts +2 -0
  54. package/dist/core/engine/callback-checkpoint-persistence.js +6 -3
  55. package/dist/core/engine/callback-creators-schedule.d.ts +2 -1
  56. package/dist/core/engine/callback-creators-schedule.js +3 -3
  57. package/dist/core/engine/callback-creators.js +4 -22
  58. package/dist/core/engine/checkpoint-io.d.ts +1 -1
  59. package/dist/core/engine/checkpoint-reads.js +11 -1
  60. package/dist/core/engine/child-workflow.js +15 -6
  61. package/dist/core/engine/construction.js +3 -0
  62. package/dist/core/engine/disposal.js +2 -0
  63. package/dist/core/engine/engine-internal-types.d.ts +4 -1
  64. package/dist/core/engine/fenced-write.d.ts +5 -3
  65. package/dist/core/engine/finalizer-status.d.ts +10 -0
  66. package/dist/core/engine/finalizer-status.js +82 -0
  67. package/dist/core/engine/index.d.ts +26 -2
  68. package/dist/core/engine/index.js +71 -8
  69. package/dist/core/engine/internals.d.ts +3 -0
  70. package/dist/core/engine/lease-health.d.ts +64 -0
  71. package/dist/core/engine/lease-health.js +0 -0
  72. package/dist/core/engine/lease-manager.d.ts +4 -2
  73. package/dist/core/engine/lease-manager.js +32 -4
  74. package/dist/core/engine/lifecycle/recovered-services.js +0 -2
  75. package/dist/core/engine/lifecycle/shared.d.ts +11 -8
  76. package/dist/core/engine/lifecycle/start-batch.js +12 -0
  77. package/dist/core/engine/lifecycle/start.d.ts +1 -1
  78. package/dist/core/engine/lifecycle/start.js +34 -5
  79. package/dist/core/engine/operations-coordination.d.ts +1 -12
  80. package/dist/core/engine/operations-coordination.js +58 -11
  81. package/dist/core/engine/operations-speculate.d.ts +1 -1
  82. package/dist/core/engine/operations-speculate.js +19 -5
  83. package/dist/core/engine/parallel-dispatch.d.ts +1 -1
  84. package/dist/core/engine/parallel-dispatch.js +1 -1
  85. package/dist/core/engine/registration.js +14 -0
  86. package/dist/core/engine/review-list-entries.d.ts +1 -1
  87. package/dist/core/engine/review-list-entries.js +6 -30
  88. package/dist/core/engine/schedule-handle.d.ts +4 -4
  89. package/dist/core/engine/schedule-handle.js +2 -2
  90. package/dist/core/engine/schedule-overlap.d.ts +11 -0
  91. package/dist/core/engine/schedule-overlap.js +50 -0
  92. package/dist/core/engine/schedule-run.d.ts +11 -3
  93. package/dist/core/engine/schedule-run.js +27 -4
  94. package/dist/core/engine/schedule-timer.js +10 -1
  95. package/dist/core/engine/schedules.d.ts +5 -4
  96. package/dist/core/engine/schedules.js +62 -56
  97. package/dist/core/engine/state-utilities.js +1 -1
  98. package/dist/core/engine/storage-io.d.ts +12 -0
  99. package/dist/core/engine/storage-io.js +49 -10
  100. package/dist/core/engine/termination/finalizer-claim.d.ts +8 -6
  101. package/dist/core/engine/termination/finalizer-claim.js +2 -1
  102. package/dist/core/engine/termination/finalizer.js +10 -14
  103. package/dist/core/engine/timeline-coordinator-constants.d.ts +3 -0
  104. package/dist/core/engine/timeline-coordinator-constants.js +1 -0
  105. package/dist/core/engine/timeline-coordinator-detail.d.ts +13 -0
  106. package/dist/core/engine/timeline-coordinator-detail.js +76 -0
  107. package/dist/core/engine/validation/schedule-options.d.ts +8 -1
  108. package/dist/core/engine/validation/schedule-options.js +18 -0
  109. package/dist/core/engine/validation/schedule.d.ts +1 -1
  110. package/dist/core/engine/validation/schedule.js +27 -3
  111. package/dist/core/engine/validation.js +66 -2
  112. package/dist/core/engine/workflow-state-stream.d.ts +5 -1
  113. package/dist/core/engine/workflow-state-stream.js +37 -14
  114. package/dist/core/events/schedule-events.d.ts +3 -4
  115. package/dist/core/events/workflow-events.d.ts +2 -1
  116. package/dist/core/list-filter-validation.d.ts +3 -0
  117. package/dist/core/list-filter-validation.js +11 -0
  118. package/dist/core/registry-snapshot.d.ts +32 -0
  119. package/dist/core/registry-snapshot.js +28 -0
  120. package/dist/core/review/index.d.ts +91 -4
  121. package/dist/core/review/index.js +29 -0
  122. package/dist/core/types/activity.d.ts +52 -5
  123. package/dist/core/types/bulk.d.ts +1 -0
  124. package/dist/core/types/list-options.d.ts +6 -0
  125. package/dist/core/types/options.d.ts +6 -5
  126. package/dist/core/types/reviews.d.ts +2 -2
  127. package/dist/core/types/schedules.d.ts +45 -2
  128. package/dist/core/types/services-resolution.d.ts +5 -5
  129. package/dist/core/types/state.d.ts +64 -0
  130. package/dist/core/types/workflow-log.d.ts +3 -2
  131. package/dist/core/types/workflow-observability.d.ts +50 -0
  132. package/dist/core/types/workflow-observability.js +0 -0
  133. package/dist/core/types/workflow-registry.d.ts +7 -0
  134. package/dist/core/types.d.ts +1 -0
  135. package/dist/core/types.js +1 -0
  136. package/dist/diagnostics/validate.d.ts +9 -30
  137. package/dist/diagnostics/validate.js +83 -21
  138. package/dist/diagnostics/version-check.d.ts +2 -2
  139. package/dist/http.js +2 -2
  140. package/dist/index.d.ts +4 -3
  141. package/dist/indexeddb.js +1 -1
  142. package/dist/server/access-policy-metadata.d.ts +92 -0
  143. package/dist/server/access-policy-metadata.js +78 -0
  144. package/dist/server/fault-to-http.d.ts +3 -7
  145. package/dist/server/fault-to-http.js +2 -34
  146. package/dist/server/handler/index.js +1 -1
  147. package/dist/server/handler/route-dispatch.d.ts +10 -3
  148. package/dist/server/handler/route-dispatch.js +19 -4
  149. package/dist/server/index.d.ts +1 -1
  150. package/dist/server/index.js +1 -0
  151. package/dist/server/interactive-operations.js +2 -0
  152. package/dist/server/openapi-error-responses.js +41 -4
  153. package/dist/server/openapi.d.ts +3 -1
  154. package/dist/server/openapi.js +4 -0
  155. package/dist/server/openrpc-document-schema.d.ts +64 -0
  156. package/dist/server/openrpc-document-schema.js +6 -26
  157. package/dist/server/openrpc.d.ts +4 -0
  158. package/dist/server/openrpc.js +9 -33
  159. package/dist/server/operation-catalog/index.d.ts +1 -1
  160. package/dist/server/operation-catalog/raise-fault.d.ts +2 -1
  161. package/dist/server/operation-catalog/types.d.ts +2 -1
  162. package/dist/server/operation-fault.d.ts +22 -8
  163. package/dist/server/operation-fault.js +65 -13
  164. package/dist/server/operation-registry.d.ts +1 -1
  165. package/dist/server/operations/aggregate-workflows.d.ts +6 -0
  166. package/dist/server/operations/aggregate-workflows.js +3 -2
  167. package/dist/server/operations/async-activity.d.ts +14 -0
  168. package/dist/server/operations/async-activity.js +88 -4
  169. package/dist/server/operations/bulk-filter-helpers.d.ts +3 -0
  170. package/dist/server/operations/bulk-filter-helpers.js +27 -3
  171. package/dist/server/operations/bulk-mutate-workflow-tags.d.ts +6 -0
  172. package/dist/server/operations/bulk-signal-workflows.d.ts +6 -0
  173. package/dist/server/operations/get-stream-chunks.js +2 -7
  174. package/dist/server/operations/get-system-lease.d.ts +19 -0
  175. package/dist/server/operations/get-system-lease.js +48 -0
  176. package/dist/server/operations/get-workflow-observability.d.ts +24 -0
  177. package/dist/server/operations/get-workflow-observability.js +80 -0
  178. package/dist/server/operations/get-workflow-result.js +2 -2
  179. package/dist/server/operations/get-workflow.d.ts +2 -2
  180. package/dist/server/operations/list-filter-query-extractor.js +15 -0
  181. package/dist/server/operations/list-reviews.js +2 -19
  182. package/dist/server/operations/list-workflows.d.ts +6 -0
  183. package/dist/server/operations/list-workflows.js +12 -3
  184. package/dist/server/operations/operation-helpers.d.ts +9 -18
  185. package/dist/server/operations/operation-helpers.js +5 -23
  186. package/dist/server/operations/purge-workflows.d.ts +3 -0
  187. package/dist/server/operations/recover-all.js +1 -9
  188. package/dist/server/operations/single-workflow-control-operation.d.ts +2 -1
  189. package/dist/server/operations/single-workflow-tag-mutation.js +2 -2
  190. package/dist/server/operations/sse-stream.js +2 -7
  191. package/dist/server/operations/storage-capabilities.d.ts +34 -0
  192. package/dist/server/operations/storage-capabilities.js +38 -0
  193. package/dist/server/operations/storage.js +8 -17
  194. package/dist/server/operations/stream-workflow-sse.js +3 -9
  195. package/dist/server/operations/update-schedule.d.ts +8 -0
  196. package/dist/server/operations/update-schedule.js +70 -7
  197. package/dist/server/operations/workflow-events-sse.js +2 -2
  198. package/dist/server/rest-binding.d.ts +7 -6
  199. package/dist/server/rest-bindings.d.ts +2 -13
  200. package/dist/server/rest-bindings.js +19 -10
  201. package/dist/server/task-queue.d.ts +7 -5
  202. package/dist/storage/bounded-ndjson-response.d.ts +5 -0
  203. package/dist/storage/bounded-ndjson-response.js +33 -0
  204. package/dist/storage/capabilities.d.ts +1 -1
  205. package/dist/storage/cloudflare-value-codec.d.ts +5 -3
  206. package/dist/storage/cloudflare-value-codec.js +1 -1
  207. package/dist/storage/compressed-storage.js +1 -1
  208. package/dist/storage/http.js +5 -37
  209. package/dist/storage/index.d.ts +7 -1
  210. package/dist/storage/interface.d.ts +16 -4
  211. package/dist/storage/interface.js +1 -1
  212. package/dist/storage/key-prefixes.d.ts +1 -1
  213. package/dist/storage/key-prefixes.js +4 -0
  214. package/dist/storage/lmdb.js +1 -1
  215. package/dist/storage/memory.js +1 -1
  216. package/dist/storage/neon.d.ts +3 -16
  217. package/dist/storage/neon.js +4 -4
  218. package/dist/storage/postgres.js +4 -4
  219. package/dist/storage/resolve.js +1 -1
  220. package/dist/storage/scoped-storage.js +1 -1
  221. package/dist/storage/testing.js +1 -1
  222. package/dist/storage/turso.js +2 -2
  223. package/dist/version.d.ts +1 -1
  224. package/dist/version.js +1 -1
  225. package/dist/web-extension.js +1 -1
  226. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import type { CommandOutput } from './types.ts';
2
- /** Checks stored workflow history against the current workflow registrations. */
2
+ /** Checks stored workflow history against the current workflow definitions. */
3
3
  export declare function executeVersionCheck(options: {
4
4
  database: string;
5
5
  workflows: string;
@@ -8,7 +8,7 @@ export async function executeVersionCheck(options) {
8
8
  };
9
9
  const { runVersionCheck } = await import("../diagnostics/version-check.js"), { formatVersionCheckReport } = await import("../diagnostics/format.js"), { BunSQLiteStorage } = await import("../storage/bun-sql.js"), storage = new BunSQLiteStorage(options.database);
10
10
  try {
11
- const registrations = await import(resolve(process.cwd(), options.workflows)), report = await runVersionCheck(storage, registrations.default);
11
+ const workflowsPath = resolve(process.cwd(), options.workflows), { loadRegistrationsFromModule } = await import("../diagnostics/validate.js"), { registrations } = await loadRegistrationsFromModule(workflowsPath), report = await runVersionCheck(storage, registrations);
12
12
  return { stdout: options.json ? JSON.stringify(report, null, 2) : formatVersionCheckReport(report), exitCode: 0 };
13
13
  } finally {
14
14
  storage[Symbol.dispose]();
package/dist/cli-main.js CHANGED
@@ -32,6 +32,7 @@ import {
32
32
  WORKFLOW_HELP_TEXT,
33
33
  writeRunLockfile
34
34
  } from "./cli/index.js";
35
+ import { CLI_SHUTDOWN_SIGNALS, createCliShutdownHandler } from "./cli/shutdown.js";
35
36
  import { Engine } from "./core/engine.js";
36
37
  import { serve } from "./server/index.js";
37
38
  const parsedArguments = (() => {
@@ -67,36 +68,16 @@ if (parsedArguments.command === "version") {
67
68
  console.log(`Health check: ${new URL("/v1/health", server.url).href}`);
68
69
  console.log(`Storage: ${parsedArguments.storage}`);
69
70
  console.log(`Database: ${parsedArguments.database}`);
70
- process.on("SIGINT", () => {
71
- console.log(`
72
- Shutting down...`);
73
- server.stop().then(async () => {
74
- try {
75
- await removeRunLockfile(server.url);
76
- } catch (error) {
77
- console.error("[weft] Failed to remove run lockfile:", error);
78
- }
79
- storage[Symbol.dispose]();
80
- process.exit(0);
81
- }).catch((error) => {
82
- console.error("[weft] Shutdown error:", error);
83
- process.exit(1);
84
- });
85
- });
86
- process.on("SIGTERM", () => {
87
- server.stop().then(async () => {
88
- try {
89
- await removeRunLockfile(server.url);
90
- } catch (error) {
91
- console.error("[weft] Failed to remove run lockfile:", error);
92
- }
93
- storage[Symbol.dispose]();
94
- process.exit(0);
95
- }).catch((error) => {
96
- console.error("[weft] Shutdown error:", error);
97
- process.exit(1);
98
- });
71
+ const shutdown = createCliShutdownHandler({
72
+ stopServer: () => server.stop(),
73
+ removeRunLockfile: () => removeRunLockfile(server.url),
74
+ disposeStorage: () => storage[Symbol.dispose](),
75
+ log: (message) => console.log(message),
76
+ reportError: (message, error) => console.error(message, error),
77
+ exit: (code) => process.exit(code)
99
78
  });
79
+ for (const signal of CLI_SHUTDOWN_SIGNALS)
80
+ process.on(signal, () => void shutdown(signal));
100
81
  } else if (parsedArguments.command === "doctor") {
101
82
  if (parsedArguments.help) {
102
83
  console.log(DOCTOR_HELP_TEXT);
@@ -0,0 +1,24 @@
1
+ import { type BatchOperation, type ConditionalBatchCondition, type ScanOptions, type Storage } from '../storage/interface.ts';
2
+ /**
3
+ * Byte-oriented raw storage surface shared by local and HTTP clients.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * import { Engine, LocalClient, MemoryStorage, type WeftClientStorage } from '@lostgradient/weft';
8
+ *
9
+ * await using engine = new Engine({ storage: new MemoryStorage() });
10
+ * const client = new LocalClient(engine);
11
+ * const storage: WeftClientStorage = client.storage;
12
+ * await storage.put('example:key', new TextEncoder().encode('value'));
13
+ * ```
14
+ */
15
+ export interface WeftClientStorage {
16
+ get(key: string): Promise<Uint8Array | null>;
17
+ put(key: string, value: Uint8Array): Promise<void>;
18
+ delete(key: string): Promise<void>;
19
+ scan(prefix: string, options?: ScanOptions): AsyncIterable<[string, Uint8Array]>;
20
+ batch(operations: BatchOperation[]): Promise<void>;
21
+ conditionalBatch(conditions: ConditionalBatchCondition[], operations: BatchOperation[]): Promise<boolean>;
22
+ }
23
+ /** Adapt an engine-owned storage backend without exposing adapter-only methods. */
24
+ export declare function createLocalClientStorage(storage: Storage): WeftClientStorage;
@@ -0,0 +1,14 @@
1
+ import {
2
+ storageBatch,
3
+ storageConditionalBatch
4
+ } from "../storage/interface.js";
5
+ export function createLocalClientStorage(storage) {
6
+ return {
7
+ get: (key) => storage.get(key),
8
+ put: (key, value) => storage.put(key, value),
9
+ delete: (key) => storage.delete(key),
10
+ scan: (prefix, options) => storage.scan(prefix, options),
11
+ batch: (operations) => storageBatch(storage, operations),
12
+ conditionalBatch: (conditions, operations) => storageConditionalBatch(storage, conditions, operations)
13
+ };
14
+ }
@@ -1,5 +1,5 @@
1
1
  import type { WeftEventMap } from '../core/events.ts';
2
- import type { QueryDefinition, ScheduleSpec, ScheduleSummary, SearchAttributeValue, SignalDefinition, SignalDeliveryOptions, UpdateDefinition } from '../core/types.ts';
2
+ import type { QueryDefinition, ScheduleSpec, ScheduleSummary, ScheduleUpdateOptions, SearchAttributeValue, SignalDefinition, SignalDeliveryOptions, UpdateDefinition } from '../core/types.ts';
3
3
  import type { WorkflowEventTail } from './event-tail.ts';
4
4
  import type { ClientHandle, ClientScheduleHandle, StartOrSignalOutcome } from './interface.ts';
5
5
  export interface WorkflowHandleDelegationClient {
@@ -62,7 +62,7 @@ export interface ScheduleHandleDelegationClient {
62
62
  pauseSchedule(id: string): Promise<void>;
63
63
  resumeSchedule(id: string): Promise<void>;
64
64
  cancelSchedule(id: string): Promise<void>;
65
- updateSchedule(id: string, newSpec: string | ScheduleSpec): Promise<void>;
65
+ updateSchedule(id: string, newSpec: string | ScheduleSpec, options?: ScheduleUpdateOptions): Promise<void>;
66
66
  getSchedule(id: string): Promise<ScheduleSummary | null>;
67
67
  }
68
68
  export declare abstract class ScheduleHandleDelegation<TClient extends ScheduleHandleDelegationClient = ScheduleHandleDelegationClient> implements ClientScheduleHandle {
@@ -72,7 +72,7 @@ export declare abstract class ScheduleHandleDelegation<TClient extends ScheduleH
72
72
  pause(): Promise<void>;
73
73
  resume(): Promise<void>;
74
74
  cancel(): Promise<void>;
75
- update(newSpec: string | ScheduleSpec): Promise<void>;
75
+ update(newSpec: string | ScheduleSpec, options?: ScheduleUpdateOptions): Promise<void>;
76
76
  describe(): Promise<ScheduleSummary | null>;
77
77
  abstract [Symbol.dispose](): void;
78
78
  }
@@ -65,8 +65,8 @@ export class ScheduleHandleDelegation {
65
65
  async cancel() {
66
66
  return this.client.cancelSchedule(this.id);
67
67
  }
68
- async update(newSpec) {
69
- return this.client.updateSchedule(this.id, newSpec);
68
+ async update(newSpec, options) {
69
+ return this.client.updateSchedule(this.id, newSpec, options);
70
70
  }
71
71
  async describe() {
72
72
  return this.client.getSchedule(this.id);
@@ -1,5 +1,5 @@
1
1
  import type { StoredStreamChunk } from '../core/context.ts';
2
- import type { BulkCancelResult, BulkDeleteResult, BulkRetryFailedResult, BulkSignalResult, BulkTagResult, CoordinatedUpdateResult, ForkOptions, ListFilter, PurgeResult, RetentionOverview, ReviewListEntry, ReviewListFilter, ScheduleSpec, ScheduleSummary, SearchAttributeValue, SignalDeliveryOptions, SubmitReviewOptions, WorkflowReplay, WorkflowState, WorkflowTimelineEntry } from '../core/types.ts';
2
+ import type { BulkCancelResult, BulkDeleteResult, BulkRetryFailedResult, BulkSignalResult, BulkTagResult, CoordinatedUpdateResult, ForkOptions, ListFilter, PendingAsyncActivityListOptions, PendingAsyncActivityPage, PurgeResult, RetentionOverview, ReviewListEntry, ReviewListFilter, ScheduleSpec, ScheduleSummary, ScheduleUpdateOptions, SearchAttributeValue, SignalDeliveryOptions, SubmitReviewOptions, WorkflowReplay, WorkflowState, WorkflowTimelineEntry } from '../core/types.ts';
3
3
  import type { UpdateResult } from './interface.ts';
4
4
  export type HttpClientRequestContext = {
5
5
  readonly baseUrl: string;
@@ -37,6 +37,8 @@ export declare function signalWorkflowRequest(context: HttpClientRequestContext,
37
37
  * workflow with `result`. Mirrors `LocalClient.activity.complete` over HTTP.
38
38
  */
39
39
  export declare function completeAsyncActivityRequest(context: HttpClientRequestContext, token: string, result?: unknown): Promise<void>;
40
+ /** List durable async activities awaiting completion for one workflow. */
41
+ export declare function listPendingAsyncActivitiesRequest(context: HttpClientRequestContext, workflowId: string, options?: PendingAsyncActivityListOptions): Promise<PendingAsyncActivityPage>;
40
42
  /**
41
43
  * Fail a deferred ("async") activity by task token. A live `Error` cannot cross
42
44
  * the wire, so the error is reduced to `message` + `name` — exactly the fields
@@ -59,8 +61,8 @@ export declare function pauseScheduleRequest(context: HttpClientRequestContext,
59
61
  export declare function resumeScheduleRequest(context: HttpClientRequestContext, id: string): Promise<void>;
60
62
  /** Cancel a recurring schedule (`DELETE /v1/schedules/:id`). */
61
63
  export declare function cancelScheduleRequest(context: HttpClientRequestContext, id: string): Promise<void>;
62
- /** Update a schedule's recurrence specification (`PATCH /v1/schedules/:id`). */
63
- export declare function updateScheduleRequest(context: HttpClientRequestContext, id: string, newSpec: string | ScheduleSpec): Promise<void>;
64
+ /** Update a schedule's cadence and mutable options (`PATCH /v1/schedules/:id`). */
65
+ export declare function updateScheduleRequest(context: HttpClientRequestContext, id: string, newSpec: string | ScheduleSpec, options?: ScheduleUpdateOptions): Promise<void>;
64
66
  /**
65
67
  * Query a named read-only accessor on a workflow. A no-input query is a GET;
66
68
  * an input payload is sent as a POST body.
@@ -139,6 +139,15 @@ export async function completeAsyncActivityRequest(context, token, result) {
139
139
  body: JSON.stringify({ token, result })
140
140
  });
141
141
  }
142
+ export async function listPendingAsyncActivitiesRequest(context, workflowId, options) {
143
+ const search = new URLSearchParams;
144
+ if (options?.limit !== void 0)
145
+ search.set("limit", String(options.limit));
146
+ if (options?.cursor !== void 0)
147
+ search.set("cursor", options.cursor);
148
+ const query = search.size > 0 ? `?${search.toString()}` : "";
149
+ return request(context.baseUrl, `/workflows/${encodeURIComponent(workflowId)}/pending-async-activities${query}`, context.headers);
150
+ }
142
151
  export async function failAsyncActivityRequest(context, token, error) {
143
152
  const reduced = { message: error instanceof Error ? error.message : String(error) };
144
153
  if (error instanceof Error)
@@ -176,10 +185,19 @@ export function cancelScheduleRequest(context, id) {
176
185
  method: "DELETE"
177
186
  });
178
187
  }
179
- export function updateScheduleRequest(context, id, newSpec) {
188
+ export function updateScheduleRequest(context, id, newSpec, options) {
189
+ const body = scheduleSpecToWireFields(newSpec);
190
+ if (options?.description !== void 0)
191
+ body.description = options.description;
192
+ if (options?.overlap !== void 0)
193
+ body.overlap = options.overlap;
194
+ if (options?.backfill !== void 0)
195
+ body.backfill = options.backfill;
196
+ if (options?.jitter !== void 0)
197
+ body.jitter = options.jitter;
180
198
  return request(context.baseUrl, `/schedules/${encodeURIComponent(id)}`, context.headers, {
181
199
  method: "PATCH",
182
- body: JSON.stringify(scheduleSpecToWireFields(newSpec))
200
+ body: JSON.stringify(body)
183
201
  });
184
202
  }
185
203
  export async function queryWorkflowRequest(context, id, name, input) {
@@ -0,0 +1,3 @@
1
+ import type { WeftClientStorage } from './client-storage.ts';
2
+ /** Build the raw-storage facade over the six specialized REST bindings. */
3
+ export declare function createHttpClientStorage(baseUrl: string, headers: Record<string, string>): WeftClientStorage;
@@ -0,0 +1,82 @@
1
+ import { readBoundedNdjsonResponse } from "../storage/bounded-ndjson-response.js";
2
+ import { decodeBase64ToBytes, encodeBytesToBase64, isRecord } from "../storage/byte-encoding.js";
3
+ import {
4
+ assertStorageBatchOperationCount
5
+ } from "../storage/interface.js";
6
+ import { request, requestResponse } from "./http-request.js";
7
+ const MAX_SCAN_RESPONSE_BYTES = 67108864;
8
+ function encodeOperation(operation) {
9
+ return operation.type === "put" ? { type: "put", key: operation.key, value: encodeBytesToBase64(operation.value) } : { type: "delete", key: operation.key };
10
+ }
11
+ function scanPath(prefix, options) {
12
+ const parameters = new URLSearchParams({ prefix });
13
+ for (const [name, value] of Object.entries(options))
14
+ if (value !== void 0)
15
+ parameters.set(name, String(value));
16
+ return `/storage?${parameters.toString()}`;
17
+ }
18
+ function scanEntry(value) {
19
+ if (!isRecord(value) || typeof value.key !== "string" || typeof value.value !== "string")
20
+ throw Error("HttpClient storage scan response contained an invalid NDJSON entry.");
21
+ return [value.key, decodeBase64ToBytes(value.value)];
22
+ }
23
+ async function* scanResponse(response) {
24
+ for await (const line of readBoundedNdjsonResponse(response, {
25
+ maximumBytes: MAX_SCAN_RESPONSE_BYTES,
26
+ sizeLimitError: () => Error("HttpClient storage scan response exceeded the maximum allowed size.")
27
+ }))
28
+ if (line.trim().length > 0)
29
+ yield scanEntry(JSON.parse(line));
30
+ }
31
+ export function createHttpClientStorage(baseUrl, headers) {
32
+ return {
33
+ async get(key) {
34
+ const response = await requestResponse(baseUrl, `/storage/${encodeURIComponent(key)}`, headers, { method: "GET" });
35
+ return response === null ? null : new Uint8Array(await response.arrayBuffer());
36
+ },
37
+ async put(key, value) {
38
+ await requestResponse(baseUrl, `/storage/${encodeURIComponent(key)}`, headers, {
39
+ method: "PUT",
40
+ headers: { "content-type": "application/octet-stream" },
41
+ body: new Blob([value])
42
+ });
43
+ },
44
+ async delete(key) {
45
+ await requestResponse(baseUrl, `/storage/${encodeURIComponent(key)}`, headers, {
46
+ method: "DELETE"
47
+ });
48
+ },
49
+ async* scan(prefix, options = {}) {
50
+ const response = await requestResponse(baseUrl, scanPath(prefix, options), headers, {
51
+ method: "GET",
52
+ headers: { accept: "application/x-ndjson" }
53
+ });
54
+ if (response !== null)
55
+ yield* scanResponse(response);
56
+ },
57
+ async batch(operations) {
58
+ assertStorageBatchOperationCount("batch operations", operations.length);
59
+ await request(baseUrl, "/storage/-/batch", headers, {
60
+ method: "POST",
61
+ body: JSON.stringify({ operations: operations.map(encodeOperation) })
62
+ });
63
+ },
64
+ async conditionalBatch(conditions, operations) {
65
+ assertStorageBatchOperationCount("conditionalBatch conditions", conditions.length);
66
+ assertStorageBatchOperationCount("conditionalBatch operations", operations.length);
67
+ const result = await request(baseUrl, "/storage/-/conditional-batch", headers, {
68
+ method: "POST",
69
+ body: JSON.stringify({
70
+ conditions: conditions.map((condition) => ({
71
+ key: condition.key,
72
+ expectedValue: condition.expectedValue === null ? null : encodeBytesToBase64(condition.expectedValue)
73
+ })),
74
+ operations: operations.map(encodeOperation)
75
+ })
76
+ });
77
+ if (!isRecord(result) || typeof result.applied !== "boolean")
78
+ throw Error('HttpClient storage conditional batch response must include a boolean "applied" field.');
79
+ return result.applied;
80
+ }
81
+ };
82
+ }
@@ -1,6 +1,7 @@
1
- import { type CatalogOperationName, type CatalogOperationTypes, type WeftClient as CatalogOperations } from '../cli/generated/operation-client.generated.ts';
1
+ import { type ClientOperationName, type ClientOperationTypes, type ClientOperations } from '../cli/generated/operation-client.generated.ts';
2
2
  import type { StoredStreamChunk } from '../core/context.ts';
3
- import type { AttributeFilterKey, BulkCancelResult, BulkDeleteResult, BulkRetryFailedResult, BulkSignalResult, BulkTagResult, CoordinatedUpdateResult, ForkOptions, ListFilter, PaginatedResult, PurgeResult, QueryDefinition, RetentionOverview, ReviewListEntry, ReviewListFilter, ScheduleFilter, ScheduleOptions, ScheduleSpec, ScheduleSummary, SearchAttributeValue, SignalDefinition, SignalDeliveryOptions, StartOrSignalSignal, SubmitReviewOptions, TypedListFilter, UpdateDefinition, WorkflowEvent, WorkflowInput, WorkflowOutput, WorkflowRegistry, WorkflowReplay, WorkflowState, WorkflowSummary, WorkflowTimelineEntry } from '../core/types.ts';
3
+ import type { AttributeFilterKey, BulkCancelResult, BulkDeleteResult, BulkRetryFailedResult, BulkSignalResult, BulkTagResult, CoordinatedUpdateResult, ForkOptions, ListFilter, PaginatedResult, PurgeResult, QueryDefinition, RetentionOverview, ReviewListEntry, ReviewListFilter, ScheduleFilter, ScheduleOptions, ScheduleSpec, ScheduleSummary, ScheduleUpdateOptions, SearchAttributeValue, SignalDefinition, SignalDeliveryOptions, StartOrSignalSignal, SubmitReviewOptions, TypedListFilter, UpdateDefinition, WorkflowEvent, WorkflowInput, WorkflowOutput, WorkflowRegistry, WorkflowReplay, WorkflowState, WorkflowSummary, WorkflowTimelineEntry } from '../core/types.ts';
4
+ import type { WeftClientStorage } from './client-storage.ts';
4
5
  import type { WorkflowEventTail } from './event-tail.ts';
5
6
  import { type HttpClientOptions } from './http-request.ts';
6
7
  import type { ClientHandle, ClientScheduleHandle, ClientStartOptions, ClientStartOrSignalOptions, UpdateResult, WeftClient, WeftClientActivity } from './interface.ts';
@@ -49,15 +50,17 @@ export declare class HttpClient implements WeftClient {
49
50
  readonly baseUrl: string;
50
51
  /** @internal Exposed for handle access. */
51
52
  readonly headers: Record<string, string>;
52
- /** Typed low-level accessor for every catalog operation over JSON-RPC. */
53
- readonly operations: CatalogOperations;
53
+ /** Typed low-level accessor over JSON-RPC and generated ordinary REST bindings. */
54
+ readonly operations: ClientOperations;
55
+ /** Raw storage administration over the byte-oriented REST bindings. */
56
+ readonly storage: WeftClientStorage;
54
57
  /**
55
58
  * Out-of-band ("async") activity completion over HTTP. POSTs to
56
59
  * `/v1/activities/{complete,fail}`; mirrors {@link LocalClient}'s `activity`.
57
60
  */
58
61
  readonly activity: WeftClientActivity;
59
62
  constructor(options?: HttpClientOptions);
60
- call<Name extends CatalogOperationName>(name: Name, input: CatalogOperationTypes[Name]['input']): Promise<CatalogOperationTypes[Name]['output']>;
63
+ call<Name extends ClientOperationName>(name: Name, input: ClientOperationTypes[Name]['input']): Promise<ClientOperationTypes[Name]['output']>;
61
64
  start<TName extends KnownWorkflowName>(type: TName, input: WorkflowInput<WorkflowRegistry, TName>, options?: ClientStartOptions): Promise<ClientHandle<WorkflowOutput<WorkflowRegistry, TName>>>;
62
65
  start<TName extends string>(type: UnknownNameWhenRegistryEmpty<TName>, input: unknown, options?: ClientStartOptions): Promise<ClientHandle>;
63
66
  startOrSignal<TName extends KnownWorkflowName>(type: TName, input: WorkflowInput<WorkflowRegistry, TName>, signal: StartOrSignalSignal, options?: ClientStartOrSignalOptions): Promise<ClientHandle<WorkflowOutput<WorkflowRegistry, TName>>>;
@@ -75,7 +78,7 @@ export declare class HttpClient implements WeftClient {
75
78
  pauseSchedule(id: string): Promise<void>;
76
79
  resumeSchedule(id: string): Promise<void>;
77
80
  cancelSchedule(id: string): Promise<void>;
78
- updateSchedule(id: string, newSpec: string | ScheduleSpec): Promise<void>;
81
+ updateSchedule(id: string, newSpec: string | ScheduleSpec, options?: ScheduleUpdateOptions): Promise<void>;
79
82
  signal(id: string, name: SignalDefinition): Promise<void>;
80
83
  signal<TInput>(id: string, name: SignalDefinition<TInput>, payload: TInput, options?: SignalDeliveryOptions): Promise<void>;
81
84
  signal(id: string, name: string, payload?: unknown, options?: SignalDeliveryOptions): Promise<void>;
@@ -1,5 +1,6 @@
1
1
  import {
2
- CATALOG_OPERATION_NAMES
2
+ CLIENT_OPERATION_NAMES,
3
+ CLIENT_REST_OPERATION_BINDINGS
3
4
  } from "../cli/generated/operation-client.generated.js";
4
5
  import { createCatalogWeftClient } from "../cli/operation-client-runtime.js";
5
6
  import { messageName } from "../core/types.js";
@@ -19,6 +20,7 @@ import {
19
20
  getTimelineRequest,
20
21
  getUpdateResultRequest,
21
22
  getWorkflowRequest,
23
+ listPendingAsyncActivitiesRequest,
22
24
  listReviewRequests,
23
25
  pauseScheduleRequest,
24
26
  purgeWorkflowRequests,
@@ -38,27 +40,31 @@ import {
38
40
  untagAllWorkflowRequests,
39
41
  updateScheduleRequest
40
42
  } from "./http-client-requests.js";
43
+ import { createHttpClientStorage } from "./http-client-storage.js";
41
44
  import { HttpHandle } from "./http-handle.js";
42
- import { httpClientCatalogTransport } from "./http-operations.js";
45
+ import { httpClientOperationTransport } from "./http-operations.js";
43
46
  import { request, resolveHttpClientConnection } from "./http-request.js";
44
47
  import { HttpScheduleHandle } from "./http-schedule-handle.js";
45
48
  import { openClientEventSubscription } from "./open-event-subscription.js";
46
49
  import { buildScheduleListSearchParams } from "./schedule-list-search-params.js";
47
50
  import { buildWorkflowListSearchParams } from "./search-params.js";
48
- import { buildStartBody, buildStartOrSignalBody, scheduleSpecToWireFields } from "./start-body.js";
51
+ import { buildScheduleBody, buildStartBody, buildStartOrSignalBody } from "./start-body.js";
49
52
 
50
53
  export class HttpClient {
51
54
  baseUrl;
52
55
  headers;
53
56
  operations;
57
+ storage;
54
58
  activity;
55
59
  #streamOptions;
56
60
  constructor(options = {}) {
57
61
  const connection = resolveHttpClientConnection(options);
58
62
  this.baseUrl = connection.baseUrl;
59
63
  this.headers = connection.headers;
60
- this.operations = createCatalogWeftClient(CATALOG_OPERATION_NAMES, httpClientCatalogTransport(this.baseUrl, this.headers));
64
+ this.operations = createCatalogWeftClient(CLIENT_OPERATION_NAMES, httpClientOperationTransport(this.baseUrl, this.headers, CLIENT_REST_OPERATION_BINDINGS));
65
+ this.storage = createHttpClientStorage(this.baseUrl, this.headers);
61
66
  this.activity = {
67
+ listPending: (workflowId, listOptions) => listPendingAsyncActivitiesRequest(this, workflowId, listOptions),
62
68
  complete: (token, result) => completeAsyncActivityRequest(this, token, result),
63
69
  completeExceptionally: (token, error) => failAsyncActivityRequest(this, token, error)
64
70
  };
@@ -82,18 +88,7 @@ export class HttpClient {
82
88
  return new HttpHandle(response.id, this, response.outcome);
83
89
  }
84
90
  async schedule(type, input, spec, options) {
85
- const body = {
86
- type,
87
- input,
88
- ...scheduleSpecToWireFields(spec)
89
- };
90
- if (options?.id !== void 0)
91
- body.id = options.id;
92
- if (options?.overlap !== void 0)
93
- body.overlap = options.overlap;
94
- if (options?.backfill !== void 0)
95
- body.backfill = options.backfill;
96
- const response = await request(this.baseUrl, "/schedules", this.headers, {
91
+ const body = buildScheduleBody(type, input, spec, options), response = await request(this.baseUrl, "/schedules", this.headers, {
97
92
  method: "POST",
98
93
  body: JSON.stringify(body)
99
94
  });
@@ -133,8 +128,8 @@ export class HttpClient {
133
128
  async cancelSchedule(id) {
134
129
  return cancelScheduleRequest(this, id);
135
130
  }
136
- async updateSchedule(id, newSpec) {
137
- return updateScheduleRequest(this, id, newSpec);
131
+ async updateSchedule(id, newSpec, options) {
132
+ return updateScheduleRequest(this, id, newSpec, options);
138
133
  }
139
134
  async signal(id, nameOrDefinition, payload, options) {
140
135
  await signalWorkflowRequest(this, id, messageName(nameOrDefinition), payload, options);
@@ -10,7 +10,7 @@
10
10
  *
11
11
  * @module client/http-operations
12
12
  */
13
- import type { CatalogTransport } from '../cli/operation-client-runtime.ts';
13
+ import type { CatalogTransport, ClientRestOperationBinding } from '../cli/operation-client-runtime.ts';
14
14
  /**
15
15
  * Build a {@link CatalogTransport} that dispatches catalog operations as
16
16
  * JSON-RPC requests to a remote Weft server at `${baseUrl}/jsonrpc`.
@@ -27,3 +27,5 @@ import type { CatalogTransport } from '../cli/operation-client-runtime.ts';
27
27
  * `HttpClientError` rather than a raw `SyntaxError`.
28
28
  */
29
29
  export declare function httpClientCatalogTransport(baseUrl: string, headers: Record<string, string>): CatalogTransport;
30
+ /** Route generated client operations over JSON-RPC or ordinary REST metadata. */
31
+ export declare function httpClientOperationTransport(baseUrl: string, headers: Record<string, string>, restBindings: Readonly<Record<string, ClientRestOperationBinding>>): CatalogTransport;
@@ -1,5 +1,5 @@
1
1
  import { isFaultCode } from "../core/fault-code.js";
2
- import { HttpClientError } from "./http-request.js";
2
+ import { HttpClientError, request } from "./http-request.js";
3
3
  function isJsonRpcFailure(value) {
4
4
  return typeof value === "object" && value !== null && "error" in value && typeof value.error === "object" && value.error !== null && "message" in value.error && typeof value.error.message === "string";
5
5
  }
@@ -40,3 +40,79 @@ export function httpClientCatalogTransport(baseUrl, headers) {
40
40
  throw new HttpClientError(response.status, `Invalid JSON-RPC response from ${endpoint}`);
41
41
  };
42
42
  }
43
+ function inputRecord(operationName, input) {
44
+ if (isRecord(input))
45
+ return input;
46
+ throw new HttpClientError(400, `Operation ${operationName} input must be an object.`);
47
+ }
48
+ function requiredString(operationName, field, value) {
49
+ if (typeof value === "string" && value.length > 0)
50
+ return value;
51
+ throw new HttpClientError(400, `Operation ${operationName} requires a non-empty string "${field}" field.`);
52
+ }
53
+ function restParameterValue(operationName, field, value) {
54
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean")
55
+ return String(value);
56
+ throw new HttpClientError(400, `Operation ${operationName} requires a string, number, or boolean "${field}" field.`);
57
+ }
58
+ function appendQueryValues(projection, operationName, field, queryParameter, value, repeating) {
59
+ if (repeating && Array.isArray(value)) {
60
+ for (const entry of value)
61
+ projection.searchParameters.append(queryParameter, restParameterValue(operationName, field, entry));
62
+ return;
63
+ }
64
+ projection.searchParameters.set(queryParameter, restParameterValue(operationName, field, value));
65
+ }
66
+ function projectRestInput(projection, operationName, field, source, value) {
67
+ if (source.kind === "path") {
68
+ const pathValue = requiredString(operationName, field, value);
69
+ projection.path = projection.path.replaceAll(`:${source.pathParam}`, encodeURIComponent(pathValue));
70
+ return;
71
+ }
72
+ if (value === void 0)
73
+ return;
74
+ if (source.kind === "query") {
75
+ appendQueryValues(projection, operationName, field, source.queryParam, value, source.repeating === !0);
76
+ return;
77
+ }
78
+ if (source.kind === "header") {
79
+ projection.requestHeaders.set(source.headerName, restParameterValue(operationName, field, value));
80
+ return;
81
+ }
82
+ if (source.kind === "body-field") {
83
+ projection.bodyFields[source.bodyField] = value;
84
+ return;
85
+ }
86
+ projection.directBody = value;
87
+ projection.directBodyMediaType = source.mediaType ?? "application/json";
88
+ }
89
+ async function callRestOperation(baseUrl, headers, operationName, binding, input) {
90
+ const fields = inputRecord(operationName, input), projection = {
91
+ path: binding.path,
92
+ searchParameters: new URLSearchParams,
93
+ requestHeaders: new Headers,
94
+ bodyFields: {},
95
+ directBody: void 0,
96
+ directBodyMediaType: void 0
97
+ };
98
+ for (const [field, source] of Object.entries(binding.inputSources))
99
+ projectRestInput(projection, operationName, field, source, fields[field]);
100
+ const query = projection.searchParameters.toString();
101
+ if (query.length > 0)
102
+ projection.path += `?${query}`;
103
+ const hasBodyFields = Object.keys(projection.bodyFields).length > 0, body = projection.directBody === void 0 ? hasBodyFields ? projection.bodyFields : void 0 : projection.directBody;
104
+ if (body !== void 0)
105
+ projection.requestHeaders.set("content-type", projection.directBodyMediaType ?? "application/json");
106
+ return request(baseUrl, projection.path, headers, {
107
+ method: binding.method,
108
+ ...[...projection.requestHeaders].length === 0 ? {} : { headers: projection.requestHeaders },
109
+ ...body === void 0 ? {} : { body: JSON.stringify(body) }
110
+ });
111
+ }
112
+ export function httpClientOperationTransport(baseUrl, headers, restBindings) {
113
+ const jsonRpc = httpClientCatalogTransport(baseUrl, headers);
114
+ return (operationName, input) => {
115
+ const restBinding = restBindings[operationName];
116
+ return restBinding === void 0 ? jsonRpc(operationName, input) : callRestOperation(baseUrl, headers, operationName, restBinding, input);
117
+ };
118
+ }
@@ -63,14 +63,14 @@ export declare function resolveHttpClientConnection(options: HttpClientOptions):
63
63
  /**
64
64
  * Error thrown when the server returns a non-2xx response.
65
65
  *
66
- * When the server sends a structured fault body (`{ error: { code, message } }`),
67
- * the wire fault `code` is surfaced as {@link HttpClientError.faultCode} and a
68
- * derived {@link HttpClientError.category} so callers can branch programmatically
69
- * instead of string-matching `message`. Both are `undefined` when the body is a
70
- * plain `{ error: string }` or carries no recognized code. The fault's typed
66
+ * When a transport response carries a recognized coarse fault code, the wire
67
+ * value is surfaced as {@link HttpClientError.faultCode} with a derived
68
+ * {@link HttpClientError.category}, so callers can branch without
69
+ * string-matching `message`. Both are `undefined` for the production flat REST
70
+ * body, which carries no coarse code. The fault's typed
71
71
  * `data` payload (e.g. `InvalidParams`'s `issues`, `NotFound`/`Conflict`'s
72
72
  * `resource`/`identifier`) is surfaced verbatim as {@link HttpClientError.data}
73
- * when the body carries a structured `data` object; `undefined` otherwise —
73
+ * when the body carries an audited `data` object; `undefined` otherwise —
74
74
  * including for a masked `EngineFailure`, whose flat body carries no `data`.
75
75
  *
76
76
  * @example
@@ -82,7 +82,7 @@ export declare function resolveHttpClientConnection(options: HttpClientOptions):
82
82
  * await client.cancel('nonexistent-id');
83
83
  * } catch (err) {
84
84
  * if (err instanceof HttpClientError) {
85
- * if (err.faultCode === 'NotFound') {
85
+ * if (err.status === 404 && err.data?.['resource'] === 'workflow') {
86
86
  * // handle a missing resource specifically
87
87
  * } else if (err.category === 'resource') {
88
88
  * // back off on rate limits and capacity faults
@@ -96,8 +96,8 @@ export declare class HttpClientError extends WeftError<'HttpClientError'> {
96
96
  /** HTTP status code of the failed response. */
97
97
  readonly status: number;
98
98
  /**
99
- * The server's stable wire fault code, when the response carried a structured
100
- * fault body. `undefined` for plain-string error bodies or unrecognized codes.
99
+ * The server's stable wire fault code, when the transport response carried a
100
+ * recognized code. `undefined` for flat REST error bodies or unrecognized codes.
101
101
  */
102
102
  readonly faultCode?: FaultCode | undefined;
103
103
  /**
@@ -107,17 +107,17 @@ export declare class HttpClientError extends WeftError<'HttpClientError'> {
107
107
  readonly category?: FailureCategory | undefined;
108
108
  /**
109
109
  * The fine-grained originating public {@link WeftErrorCode} the server
110
- * attached (e.g. `WorkflowNotFoundError`), when the structured fault carried
111
- * one. This is what makes cross-transport branching work: a producer can call
110
+ * attached (e.g. `WorkflowNotFoundError`), when the response carried one.
111
+ * This is what makes cross-transport branching work: a producer can call
112
112
  * `isWeftFault(error, 'WorkflowNotFoundError')` and have it match over HTTP
113
113
  * exactly as it matches the in-process typed error. `undefined` when the fault
114
- * carried only the coarse {@link faultCode} (most faults) or no structured body.
114
+ * carried only the coarse {@link faultCode} (most faults) or no recognized code.
115
115
  */
116
116
  readonly weftCode?: WeftErrorCode | undefined;
117
117
  /**
118
118
  * The fault's wire `data` payload, when the response carried a structured
119
- * body (`{ error: { data } }` for REST, `error.data` for JSON-RPC). Shape is
120
- * fault-code-dependent — see {@link FaultCode} and the server's
119
+ * body (`{ error, data }` for production REST or `error.data` for JSON-RPC).
120
+ * Shape is fault-code-dependent — see {@link FaultCode} and the server's
121
121
  * `OperationFault` per-code `data` union for what each code carries (e.g.
122
122
  * `InvalidParams.data.issues`, `NotFound.data.resource`). `undefined` for
123
123
  * plain-string error bodies, bodies with no `data` field, or a `data` field
@@ -138,3 +138,9 @@ export declare class HttpClientError extends WeftError<'HttpClientError'> {
138
138
  });
139
139
  }
140
140
  export declare function request<T>(baseUrl: string, path: string, baseHeaders: Record<string, string>, options?: RequestInit): Promise<T>;
141
+ /**
142
+ * Execute a REST request with the canonical {@link HttpClientError} shaping
143
+ * while leaving the successful response body available to binary or streaming
144
+ * client surfaces.
145
+ */
146
+ export declare function requestResponse(baseUrl: string, path: string, baseHeaders: Record<string, string>, options?: RequestInit): Promise<Response | null>;