@lostgradient/weft 0.12.0 → 0.13.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 +1 -1
- package/dist/cli/api.d.ts +2 -0
- package/dist/cli/api.js +3 -4
- package/dist/cli/generated/operation-catalog.snapshot.json +508 -12
- package/dist/cli/generated/operation-client.generated.d.ts +118 -10
- package/dist/cli/generated/operation-client.generated.js +74 -1
- package/dist/cli/operation-catalog-snapshot.d.ts +11 -2
- package/dist/cli/operation-catalog-snapshot.js +14 -5
- package/dist/cli/operation-client-runtime.d.ts +29 -0
- package/dist/client/client-storage.d.ts +24 -0
- package/dist/client/client-storage.js +14 -0
- package/dist/client/handle-delegation.d.ts +3 -3
- package/dist/client/handle-delegation.js +2 -2
- package/dist/client/http-client-requests.d.ts +5 -3
- package/dist/client/http-client-requests.js +20 -2
- package/dist/client/http-client-storage.d.ts +3 -0
- package/dist/client/http-client-storage.js +110 -0
- package/dist/client/http-client.d.ts +9 -6
- package/dist/client/http-client.js +13 -18
- package/dist/client/http-operations.d.ts +3 -1
- package/dist/client/http-operations.js +77 -1
- package/dist/client/http-request.d.ts +15 -8
- package/dist/client/http-request.js +19 -7
- package/dist/client/in-process-operations.d.ts +2 -2
- package/dist/client/in-process-operations.js +2 -2
- package/dist/client/index.d.ts +5 -1
- package/dist/client/index.js +13 -2
- package/dist/client/interface.d.ts +26 -26
- package/dist/client/local.d.ts +9 -6
- package/dist/client/local.js +9 -4
- package/dist/client/search-params.js +10 -6
- package/dist/client/start-body.d.ts +3 -1
- package/dist/client/start-body.js +9 -0
- package/dist/core/bulk-workflow-filter.d.ts +2 -1
- package/dist/core/bulk-workflow-filter.js +5 -1
- package/dist/core/engine/async-activity-records.d.ts +12 -1
- package/dist/core/engine/async-activity-records.js +81 -2
- package/dist/core/engine/bulk-operations-purge.js +16 -1
- package/dist/core/engine/bulk-operations-shared.js +2 -0
- package/dist/core/engine/callback-creators-schedule.d.ts +2 -1
- package/dist/core/engine/callback-creators-schedule.js +3 -3
- package/dist/core/engine/checkpoint-reads.js +11 -1
- package/dist/core/engine/child-workflow.js +15 -6
- package/dist/core/engine/construction.js +3 -0
- package/dist/core/engine/disposal.js +2 -0
- package/dist/core/engine/engine-internal-types.d.ts +4 -1
- package/dist/core/engine/fenced-write.d.ts +5 -3
- package/dist/core/engine/finalizer-status.d.ts +10 -0
- package/dist/core/engine/finalizer-status.js +82 -0
- package/dist/core/engine/index.d.ts +26 -2
- package/dist/core/engine/index.js +71 -8
- package/dist/core/engine/internals.d.ts +3 -0
- package/dist/core/engine/lease-health.d.ts +64 -0
- package/dist/core/engine/lease-health.js +0 -0
- package/dist/core/engine/lease-manager.d.ts +4 -2
- package/dist/core/engine/lease-manager.js +32 -4
- package/dist/core/engine/lifecycle/recovered-services.js +0 -2
- package/dist/core/engine/lifecycle/shared.d.ts +11 -8
- package/dist/core/engine/lifecycle/start-batch.js +12 -0
- package/dist/core/engine/lifecycle/start.d.ts +1 -1
- package/dist/core/engine/lifecycle/start.js +34 -5
- package/dist/core/engine/operations-coordination.d.ts +1 -12
- package/dist/core/engine/operations-coordination.js +57 -10
- package/dist/core/engine/operations-speculate.d.ts +1 -1
- package/dist/core/engine/operations-speculate.js +19 -5
- package/dist/core/engine/registration.js +14 -0
- package/dist/core/engine/schedule-handle.d.ts +4 -4
- package/dist/core/engine/schedule-handle.js +2 -2
- package/dist/core/engine/schedule-overlap.d.ts +11 -0
- package/dist/core/engine/schedule-overlap.js +50 -0
- package/dist/core/engine/schedule-run.d.ts +11 -3
- package/dist/core/engine/schedule-run.js +27 -4
- package/dist/core/engine/schedule-timer.js +10 -1
- package/dist/core/engine/schedules.d.ts +5 -4
- package/dist/core/engine/schedules.js +62 -56
- package/dist/core/engine/state-utilities.js +1 -1
- package/dist/core/engine/storage-io.d.ts +12 -0
- package/dist/core/engine/storage-io.js +49 -10
- package/dist/core/engine/termination/finalizer-claim.d.ts +8 -6
- package/dist/core/engine/termination/finalizer-claim.js +2 -1
- package/dist/core/engine/termination/finalizer.js +10 -14
- package/dist/core/engine/timeline-coordinator-constants.d.ts +3 -0
- package/dist/core/engine/timeline-coordinator-constants.js +1 -0
- package/dist/core/engine/timeline-coordinator-detail.d.ts +13 -0
- package/dist/core/engine/timeline-coordinator-detail.js +76 -0
- package/dist/core/engine/validation/schedule-options.d.ts +8 -1
- package/dist/core/engine/validation/schedule-options.js +18 -0
- package/dist/core/engine/validation/schedule.d.ts +1 -1
- package/dist/core/engine/validation/schedule.js +27 -3
- package/dist/core/engine/validation.js +66 -2
- package/dist/core/engine/workflow-state-stream.d.ts +5 -1
- package/dist/core/engine/workflow-state-stream.js +37 -14
- package/dist/core/events/schedule-events.d.ts +3 -4
- package/dist/core/events/workflow-events.d.ts +2 -1
- package/dist/core/list-filter-validation.d.ts +3 -0
- package/dist/core/list-filter-validation.js +11 -0
- package/dist/core/registry-snapshot.d.ts +32 -0
- package/dist/core/registry-snapshot.js +28 -0
- package/dist/core/review/index.d.ts +4 -4
- package/dist/core/types/activity.d.ts +52 -5
- package/dist/core/types/bulk.d.ts +1 -0
- package/dist/core/types/list-options.d.ts +6 -0
- package/dist/core/types/options.d.ts +6 -5
- package/dist/core/types/reviews.d.ts +2 -2
- package/dist/core/types/schedules.d.ts +45 -2
- package/dist/core/types/services-resolution.d.ts +5 -5
- package/dist/core/types/state.d.ts +64 -0
- package/dist/core/types/workflow-log.d.ts +3 -2
- package/dist/core/types/workflow-observability.d.ts +50 -0
- package/dist/core/types/workflow-observability.js +0 -0
- package/dist/core/types/workflow-registry.d.ts +7 -0
- package/dist/core/types.d.ts +1 -0
- package/dist/core/types.js +1 -0
- package/dist/http.js +2 -2
- package/dist/index.d.ts +4 -3
- package/dist/indexeddb.js +1 -1
- package/dist/server/access-policy-metadata.d.ts +92 -0
- package/dist/server/access-policy-metadata.js +78 -0
- package/dist/server/fault-to-http.d.ts +3 -7
- package/dist/server/fault-to-http.js +2 -34
- package/dist/server/handler/index.js +1 -1
- package/dist/server/handler/route-dispatch.d.ts +10 -3
- package/dist/server/handler/route-dispatch.js +19 -4
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -0
- package/dist/server/interactive-operations.js +2 -0
- package/dist/server/openapi-error-responses.js +55 -4
- package/dist/server/openapi.d.ts +3 -1
- package/dist/server/openapi.js +4 -0
- package/dist/server/openrpc-document-schema.d.ts +64 -0
- package/dist/server/openrpc-document-schema.js +6 -26
- package/dist/server/openrpc.d.ts +4 -0
- package/dist/server/openrpc.js +9 -33
- package/dist/server/operation-fault.d.ts +24 -7
- package/dist/server/operation-fault.js +65 -13
- package/dist/server/operations/aggregate-workflows.d.ts +6 -0
- package/dist/server/operations/aggregate-workflows.js +3 -2
- package/dist/server/operations/async-activity.d.ts +14 -0
- package/dist/server/operations/async-activity.js +88 -4
- package/dist/server/operations/bulk-filter-helpers.d.ts +3 -0
- package/dist/server/operations/bulk-filter-helpers.js +27 -3
- package/dist/server/operations/bulk-mutate-workflow-tags.d.ts +6 -0
- package/dist/server/operations/bulk-signal-workflows.d.ts +6 -0
- package/dist/server/operations/get-stream-chunks.js +2 -7
- package/dist/server/operations/get-system-lease.d.ts +19 -0
- package/dist/server/operations/get-system-lease.js +48 -0
- package/dist/server/operations/get-workflow-observability.d.ts +24 -0
- package/dist/server/operations/get-workflow-observability.js +80 -0
- package/dist/server/operations/get-workflow-result.js +2 -2
- package/dist/server/operations/get-workflow.d.ts +2 -2
- package/dist/server/operations/list-filter-query-extractor.js +15 -0
- package/dist/server/operations/list-workflows.d.ts +6 -0
- package/dist/server/operations/list-workflows.js +12 -3
- package/dist/server/operations/operation-helpers.d.ts +9 -18
- package/dist/server/operations/operation-helpers.js +5 -23
- package/dist/server/operations/purge-workflows.d.ts +3 -0
- package/dist/server/operations/recover-all.js +2 -1
- package/dist/server/operations/single-workflow-tag-mutation.js +2 -2
- package/dist/server/operations/sse-stream.js +2 -7
- package/dist/server/operations/storage-capabilities.d.ts +34 -0
- package/dist/server/operations/storage-capabilities.js +38 -0
- package/dist/server/operations/storage.js +8 -17
- package/dist/server/operations/stream-workflow-sse.js +3 -9
- package/dist/server/operations/update-schedule.d.ts +8 -0
- package/dist/server/operations/update-schedule.js +70 -7
- package/dist/server/operations/workflow-events-sse.js +2 -2
- package/dist/server/rest-binding.d.ts +7 -6
- package/dist/server/rest-bindings.d.ts +2 -13
- package/dist/server/rest-bindings.js +19 -10
- package/dist/server/task-queue.d.ts +7 -5
- package/dist/storage/capabilities.d.ts +1 -1
- package/dist/storage/cloudflare-value-codec.d.ts +5 -3
- package/dist/storage/cloudflare-value-codec.js +1 -1
- package/dist/storage/compressed-storage.js +1 -1
- package/dist/storage/index.d.ts +7 -1
- package/dist/storage/interface.d.ts +16 -4
- package/dist/storage/interface.js +1 -1
- package/dist/storage/key-prefixes.d.ts +1 -1
- package/dist/storage/key-prefixes.js +4 -0
- package/dist/storage/lmdb.js +1 -1
- package/dist/storage/memory.js +1 -1
- package/dist/storage/neon.js +4 -4
- package/dist/storage/postgres.js +4 -4
- package/dist/storage/resolve.js +1 -1
- package/dist/storage/scoped-storage.js +1 -1
- package/dist/storage/testing.js +1 -1
- package/dist/storage/turso.js +2 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/web-extension.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { decodeBase64ToBytes, encodeBytesToBase64, isRecord } from "../storage/byte-encoding.js";
|
|
2
|
+
import {
|
|
3
|
+
assertStorageBatchOperationCount
|
|
4
|
+
} from "../storage/interface.js";
|
|
5
|
+
import { request, requestResponse } from "./http-request.js";
|
|
6
|
+
const MAX_SCAN_RESPONSE_BYTES = 67108864;
|
|
7
|
+
function encodeOperation(operation) {
|
|
8
|
+
return operation.type === "put" ? { type: "put", key: operation.key, value: encodeBytesToBase64(operation.value) } : { type: "delete", key: operation.key };
|
|
9
|
+
}
|
|
10
|
+
function scanPath(prefix, options) {
|
|
11
|
+
const parameters = new URLSearchParams({ prefix });
|
|
12
|
+
for (const [name, value] of Object.entries(options))
|
|
13
|
+
if (value !== void 0)
|
|
14
|
+
parameters.set(name, String(value));
|
|
15
|
+
return `/storage?${parameters.toString()}`;
|
|
16
|
+
}
|
|
17
|
+
function scanEntry(value) {
|
|
18
|
+
if (!isRecord(value) || typeof value.key !== "string" || typeof value.value !== "string")
|
|
19
|
+
throw Error("HttpClient storage scan response contained an invalid NDJSON entry.");
|
|
20
|
+
return [value.key, decodeBase64ToBytes(value.value)];
|
|
21
|
+
}
|
|
22
|
+
async function releaseScanReader(reader, reachedEndOfStream) {
|
|
23
|
+
if (!reachedEndOfStream)
|
|
24
|
+
try {
|
|
25
|
+
await reader.cancel();
|
|
26
|
+
} catch {}
|
|
27
|
+
reader.releaseLock();
|
|
28
|
+
}
|
|
29
|
+
async function* scanResponse(response) {
|
|
30
|
+
if (response.body === null)
|
|
31
|
+
return;
|
|
32
|
+
const reader = response.body.getReader(), decoder = new TextDecoder;
|
|
33
|
+
let bufferedText = "", bytesRead = 0, reachedEndOfStream = !1;
|
|
34
|
+
try {
|
|
35
|
+
while (!0) {
|
|
36
|
+
const { done, value } = await reader.read();
|
|
37
|
+
if (done) {
|
|
38
|
+
reachedEndOfStream = !0;
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
bytesRead += value.byteLength;
|
|
42
|
+
if (bytesRead > MAX_SCAN_RESPONSE_BYTES)
|
|
43
|
+
throw Error("HttpClient storage scan response exceeded the maximum allowed size.");
|
|
44
|
+
bufferedText += decoder.decode(value, { stream: !0 });
|
|
45
|
+
const lines = bufferedText.split(`
|
|
46
|
+
`);
|
|
47
|
+
bufferedText = lines.pop() ?? "";
|
|
48
|
+
for (const line of lines)
|
|
49
|
+
if (line.trim().length > 0)
|
|
50
|
+
yield scanEntry(JSON.parse(line));
|
|
51
|
+
}
|
|
52
|
+
bufferedText += decoder.decode();
|
|
53
|
+
if (bufferedText.trim().length > 0)
|
|
54
|
+
yield scanEntry(JSON.parse(bufferedText));
|
|
55
|
+
} finally {
|
|
56
|
+
await releaseScanReader(reader, reachedEndOfStream);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export function createHttpClientStorage(baseUrl, headers) {
|
|
60
|
+
return {
|
|
61
|
+
async get(key) {
|
|
62
|
+
const response = await requestResponse(baseUrl, `/storage/${encodeURIComponent(key)}`, headers, { method: "GET" });
|
|
63
|
+
return response === null ? null : new Uint8Array(await response.arrayBuffer());
|
|
64
|
+
},
|
|
65
|
+
async put(key, value) {
|
|
66
|
+
await requestResponse(baseUrl, `/storage/${encodeURIComponent(key)}`, headers, {
|
|
67
|
+
method: "PUT",
|
|
68
|
+
headers: { "content-type": "application/octet-stream" },
|
|
69
|
+
body: new Blob([value])
|
|
70
|
+
});
|
|
71
|
+
},
|
|
72
|
+
async delete(key) {
|
|
73
|
+
await requestResponse(baseUrl, `/storage/${encodeURIComponent(key)}`, headers, {
|
|
74
|
+
method: "DELETE"
|
|
75
|
+
});
|
|
76
|
+
},
|
|
77
|
+
async* scan(prefix, options = {}) {
|
|
78
|
+
const response = await requestResponse(baseUrl, scanPath(prefix, options), headers, {
|
|
79
|
+
method: "GET",
|
|
80
|
+
headers: { accept: "application/x-ndjson" }
|
|
81
|
+
});
|
|
82
|
+
if (response !== null)
|
|
83
|
+
yield* scanResponse(response);
|
|
84
|
+
},
|
|
85
|
+
async batch(operations) {
|
|
86
|
+
assertStorageBatchOperationCount("batch operations", operations.length);
|
|
87
|
+
await request(baseUrl, "/storage/-/batch", headers, {
|
|
88
|
+
method: "POST",
|
|
89
|
+
body: JSON.stringify({ operations: operations.map(encodeOperation) })
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
async conditionalBatch(conditions, operations) {
|
|
93
|
+
assertStorageBatchOperationCount("conditionalBatch conditions", conditions.length);
|
|
94
|
+
assertStorageBatchOperationCount("conditionalBatch operations", operations.length);
|
|
95
|
+
const result = await request(baseUrl, "/storage/-/conditional-batch", headers, {
|
|
96
|
+
method: "POST",
|
|
97
|
+
body: JSON.stringify({
|
|
98
|
+
conditions: conditions.map((condition) => ({
|
|
99
|
+
key: condition.key,
|
|
100
|
+
expectedValue: condition.expectedValue === null ? null : encodeBytesToBase64(condition.expectedValue)
|
|
101
|
+
})),
|
|
102
|
+
operations: operations.map(encodeOperation)
|
|
103
|
+
})
|
|
104
|
+
});
|
|
105
|
+
if (!isRecord(result) || typeof result.applied !== "boolean")
|
|
106
|
+
throw Error('HttpClient storage conditional batch response must include a boolean "applied" field.');
|
|
107
|
+
return result.applied;
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { type
|
|
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
|
|
53
|
-
readonly operations:
|
|
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
|
|
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
|
-
|
|
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 {
|
|
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
|
|
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(
|
|
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
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
66
|
+
* When the server sends a fault body with a recognized coarse `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
|
|
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.
|
|
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
|
|
@@ -116,7 +116,8 @@ export declare class HttpClientError extends WeftError<'HttpClientError'> {
|
|
|
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
|
|
119
|
+
* body (`{ error, data }` for production REST, nested `{ error: { data } }`
|
|
120
|
+
* for structured REST responses, or `error.data` for JSON-RPC). Shape is
|
|
120
121
|
* fault-code-dependent — see {@link FaultCode} and the server's
|
|
121
122
|
* `OperationFault` per-code `data` union for what each code carries (e.g.
|
|
122
123
|
* `InvalidParams.data.issues`, `NotFound.data.resource`). `undefined` for
|
|
@@ -138,3 +139,9 @@ export declare class HttpClientError extends WeftError<'HttpClientError'> {
|
|
|
138
139
|
});
|
|
139
140
|
}
|
|
140
141
|
export declare function request<T>(baseUrl: string, path: string, baseHeaders: Record<string, string>, options?: RequestInit): Promise<T>;
|
|
142
|
+
/**
|
|
143
|
+
* Execute a REST request with the canonical {@link HttpClientError} shaping
|
|
144
|
+
* while leaving the successful response body available to binary or streaming
|
|
145
|
+
* client surfaces.
|
|
146
|
+
*/
|
|
147
|
+
export declare function requestResponse(baseUrl: string, path: string, baseHeaders: Record<string, string>, options?: RequestInit): Promise<Response | null>;
|
|
@@ -41,6 +41,14 @@ function buildRequestHeaders(baseHeaders, options) {
|
|
|
41
41
|
function isFlatErrorBody(value) {
|
|
42
42
|
return value !== null && typeof value === "object" && typeof value.error === "string";
|
|
43
43
|
}
|
|
44
|
+
function parseFlatErrorBody(body) {
|
|
45
|
+
const weftCode = isWeftErrorCode(body.weftCode) ? body.weftCode : void 0, data = isRecord(body.data) ? body.data : void 0;
|
|
46
|
+
return {
|
|
47
|
+
message: body.error,
|
|
48
|
+
...weftCode === void 0 ? {} : { weftCode },
|
|
49
|
+
...data === void 0 ? {} : { data }
|
|
50
|
+
};
|
|
51
|
+
}
|
|
44
52
|
function isStructuredErrorBody(value) {
|
|
45
53
|
if (value === null || typeof value !== "object")
|
|
46
54
|
return !1;
|
|
@@ -69,16 +77,22 @@ async function parseErrorBody(response) {
|
|
|
69
77
|
base.data = data;
|
|
70
78
|
return isFaultCode(code) ? { ...base, faultCode: code } : base;
|
|
71
79
|
}
|
|
72
|
-
if (isFlatErrorBody(body) && body.error)
|
|
73
|
-
|
|
74
|
-
return weftCode === void 0 ? { message: body.error } : { message: body.error, weftCode };
|
|
75
|
-
}
|
|
80
|
+
if (isFlatErrorBody(body) && body.error)
|
|
81
|
+
return parseFlatErrorBody(body);
|
|
76
82
|
return { message: response.statusText };
|
|
77
83
|
} catch {
|
|
78
84
|
return { message: response.statusText };
|
|
79
85
|
}
|
|
80
86
|
}
|
|
81
87
|
export async function request(baseUrl, path, baseHeaders, options) {
|
|
88
|
+
const response = await requestResponse(baseUrl, path, baseHeaders, options);
|
|
89
|
+
if (response === null)
|
|
90
|
+
return null;
|
|
91
|
+
if (response.status === 204)
|
|
92
|
+
return;
|
|
93
|
+
return response.json();
|
|
94
|
+
}
|
|
95
|
+
export async function requestResponse(baseUrl, path, baseHeaders, options) {
|
|
82
96
|
const headers = buildRequestHeaders(baseHeaders, options), response = await fetch(`${baseUrl}/v1${path}`, { ...options, headers });
|
|
83
97
|
if (response.status === 404 && (!options?.method || options.method === "GET"))
|
|
84
98
|
return null;
|
|
@@ -86,7 +100,5 @@ export async function request(baseUrl, path, baseHeaders, options) {
|
|
|
86
100
|
const { message, faultCode, weftCode, data } = await parseErrorBody(response);
|
|
87
101
|
throw new HttpClientError(response.status, message, { faultCode, weftCode, data });
|
|
88
102
|
}
|
|
89
|
-
|
|
90
|
-
return;
|
|
91
|
-
return response.json();
|
|
103
|
+
return response;
|
|
92
104
|
}
|
|
@@ -22,9 +22,9 @@ import type { Engine } from '../core/engine.ts';
|
|
|
22
22
|
*
|
|
23
23
|
* The registry and trusted principal are constructed once and reused across
|
|
24
24
|
* calls. Operations run with `transport: 'jsonRpcHttp'` so input/output
|
|
25
|
-
* validation and unknown-key handling match the remote
|
|
25
|
+
* validation and unknown-key handling match the selected remote transport.
|
|
26
26
|
* A failed dispatch throws with the fault message, mirroring the HTTP
|
|
27
27
|
* transport's `throw new Error(result.error.message)` contract so both clients
|
|
28
28
|
* surface operation faults the same way.
|
|
29
29
|
*/
|
|
30
|
-
export declare function inProcessCatalogTransport(engine: Engine): CatalogTransport;
|
|
30
|
+
export declare function inProcessCatalogTransport(engine: Engine, restOperationNames?: ReadonlySet<string>): CatalogTransport;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { executeOperation } from "../server/operation-catalog.js";
|
|
2
2
|
import { principalFromStdioLocal } from "../server/principal.js";
|
|
3
3
|
import { createLiveOperationRegistry } from "../server/rest-bindings.js";
|
|
4
|
-
export function inProcessCatalogTransport(engine) {
|
|
4
|
+
export function inProcessCatalogTransport(engine, restOperationNames = new Set) {
|
|
5
5
|
const registry = createLiveOperationRegistry(), principal = principalFromStdioLocal();
|
|
6
6
|
return async (operationName, input) => {
|
|
7
7
|
const result = await executeOperation(operationName, input, {
|
|
8
8
|
principal,
|
|
9
9
|
engine,
|
|
10
|
-
transport: "jsonRpcHttp",
|
|
10
|
+
transport: restOperationNames.has(operationName) ? "http-rest" : "jsonRpcHttp",
|
|
11
11
|
registry
|
|
12
12
|
});
|
|
13
13
|
if (!result.ok)
|
package/dist/client/index.d.ts
CHANGED
|
@@ -7,8 +7,12 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @module client/index
|
|
9
9
|
*/
|
|
10
|
-
export {
|
|
10
|
+
export { WorkflowCancelledEvent, WorkflowCompletedEvent, WorkflowFailedEvent, WorkflowResumedEvent, WorkflowStartedEvent, WorkflowSuspendedEvent, WorkflowTeardownEvent, WorkflowTimedOutEvent, } from '../core/events/workflow-events.ts';
|
|
11
|
+
export { isFaultCode, type FaultCode } from '../core/fault-code.ts';
|
|
12
|
+
export type { PendingAsyncActivityInfo, PendingAsyncActivityListOptions, PendingAsyncActivityPage, } from '../core/types.ts';
|
|
13
|
+
export { WeftError, isWeftError, isWeftErrorCode, isWeftErrorLike, isWeftFault, } from '../core/weft-error.ts';
|
|
11
14
|
export type { WeftErrorCode } from '../core/weft-error.ts';
|
|
15
|
+
export type { WeftClientStorage } from './client-storage.ts';
|
|
12
16
|
export type { WorkflowEventStreamOptions, WorkflowEventTransport } from './event-stream-options.ts';
|
|
13
17
|
export type { WorkflowEventTail } from './event-tail.ts';
|
|
14
18
|
export { HttpClient } from './http-client.ts';
|
package/dist/client/index.js
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
export {
|
|
2
|
+
WorkflowCancelledEvent,
|
|
3
|
+
WorkflowCompletedEvent,
|
|
4
|
+
WorkflowFailedEvent,
|
|
5
|
+
WorkflowResumedEvent,
|
|
6
|
+
WorkflowStartedEvent,
|
|
7
|
+
WorkflowSuspendedEvent,
|
|
8
|
+
WorkflowTeardownEvent,
|
|
9
|
+
WorkflowTimedOutEvent
|
|
10
|
+
} from "../core/events/workflow-events.js";
|
|
11
|
+
export { isFaultCode } from "../core/fault-code.js";
|
|
12
|
+
export {
|
|
13
|
+
WeftError,
|
|
2
14
|
isWeftError,
|
|
3
15
|
isWeftErrorCode,
|
|
4
16
|
isWeftErrorLike,
|
|
5
|
-
isWeftFault
|
|
6
|
-
WeftError
|
|
17
|
+
isWeftFault
|
|
7
18
|
} from "../core/weft-error.js";
|
|
8
19
|
export { HttpClient } from "./http-client.js";
|
|
9
20
|
export { HttpClientError } from "./http-request.js";
|
|
@@ -5,11 +5,12 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module client/interface
|
|
7
7
|
*/
|
|
8
|
-
import type {
|
|
8
|
+
import type { ClientOperationName, ClientOperationTypes, ClientOperations } from '../cli/generated/operation-client.generated.ts';
|
|
9
9
|
import type { StoredStreamChunk } from '../core/context.ts';
|
|
10
10
|
import type { StartOrSignalOutcome as EngineStartOrSignalOutcome } from '../core/engine/handles.ts';
|
|
11
11
|
import type { TypedEventTarget, WeftEventMap } from '../core/events.ts';
|
|
12
|
-
import type { AttributeFilterKey, BulkCancelResult, BulkDeleteResult, BulkRetryFailedResult, BulkSignalResult, BulkTagResult, CoordinatedUpdateResult, ForkOptions, ListFilter, PaginatedResult, PurgeResult, QueryDefinition, RetentionOverview, ReviewListEntry, ReviewListFilter, ScheduleFilter, ScheduleOptions, ScheduleSpec, ScheduleSummary, SearchAttributeValue, SignalDefinition, SignalDeliveryOptions, StartOptions, StartOrSignalOptions, StartOrSignalSignal, SubmitReviewOptions, TypedListFilter, UpdateDefinition, WorkflowEvent, WorkflowInput, WorkflowOutput, WorkflowRegistry, WorkflowReplay, WorkflowState, WorkflowSummary, WorkflowTimelineEntry } from '../core/types.ts';
|
|
12
|
+
import type { AttributeFilterKey, BulkCancelResult, BulkDeleteResult, BulkRetryFailedResult, BulkSignalResult, BulkTagResult, CoordinatedUpdateResult, ForkOptions, ListFilter, PaginatedResult, PendingAsyncActivityListOptions, PendingAsyncActivityPage, PurgeResult, QueryDefinition, RetentionOverview, ReviewListEntry, ReviewListFilter, ScheduleUpdateOptions as ScheduleEdit, ScheduleFilter, ScheduleOptions, ScheduleSpec, ScheduleSummary, SearchAttributeValue, SignalDefinition, SignalDeliveryOptions, StartOptions, StartOrSignalOptions, StartOrSignalSignal, SubmitReviewOptions, TypedListFilter, UpdateDefinition, WorkflowEvent, WorkflowInput, WorkflowOutput, WorkflowRegistry, WorkflowReplay, WorkflowState, WorkflowSummary, WorkflowTimelineEntry } from '../core/types.ts';
|
|
13
|
+
import type { WeftClientStorage } from './client-storage.ts';
|
|
13
14
|
import type { WorkflowEventTail } from './event-tail.ts';
|
|
14
15
|
import type { KnownWorkflowName, UnknownNameWhenRegistryEmpty } from './workflow-name-typing.ts';
|
|
15
16
|
/**
|
|
@@ -197,8 +198,8 @@ export interface ClientScheduleHandle extends Disposable {
|
|
|
197
198
|
resume(): Promise<void>;
|
|
198
199
|
/** Cancel this schedule. */
|
|
199
200
|
cancel(): Promise<void>;
|
|
200
|
-
/** Update the schedule
|
|
201
|
-
update(newSpec: string | ScheduleSpec): Promise<void>;
|
|
201
|
+
/** Update the schedule cadence and optional mutable schedule settings. */
|
|
202
|
+
update(newSpec: string | ScheduleSpec, options?: ScheduleEdit): Promise<void>;
|
|
202
203
|
/** Read the latest persisted summary for this schedule. */
|
|
203
204
|
describe(): Promise<ScheduleSummary | null>;
|
|
204
205
|
}
|
|
@@ -212,24 +213,21 @@ export type UpdateResult = {
|
|
|
212
213
|
* Out-of-band ("async") activity completion surface, shared by every client.
|
|
213
214
|
*
|
|
214
215
|
* An activity that called `ActivityContext.completeAsync()` parks its workflow
|
|
215
|
-
* until an external system resolves it by
|
|
216
|
-
* the
|
|
217
|
-
* directly; server mode
|
|
218
|
-
*
|
|
219
|
-
* consumes the single-use token before re-adoption and strands the workflow. The
|
|
220
|
-
* token is a deterministic identifier, not a secret (see `completeAsync`).
|
|
216
|
+
* until an external system resolves it by durable task token. `listPending()`
|
|
217
|
+
* queries the durable record after a missed live event or process restart.
|
|
218
|
+
* Library mode calls the engine directly; server mode uses the matching REST
|
|
219
|
+
* operations. The token is a deterministic identifier, not a secret.
|
|
221
220
|
*
|
|
222
221
|
* @example
|
|
223
222
|
* ```ts
|
|
224
|
-
* import {
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
* // `token` comes from the engine's `activity:async-pending` event:
|
|
228
|
-
* // await activity.complete(token, { approved: true });
|
|
229
|
-
* void activity;
|
|
223
|
+
* import type { WeftClientActivity } from '@lostgradient/weft/client';
|
|
224
|
+
* declare const activity: WeftClientActivity;
|
|
225
|
+
* void activity.listPending('order-1');
|
|
230
226
|
* ```
|
|
231
227
|
*/
|
|
232
228
|
export interface WeftClientActivity {
|
|
229
|
+
/** List a bounded page of durable activities awaiting completion for one workflow. */
|
|
230
|
+
listPending(workflowId: string, options?: PendingAsyncActivityListOptions): Promise<PendingAsyncActivityPage>;
|
|
233
231
|
/** Complete a deferred activity by token, resuming its workflow with `result` (optional; omitted/`undefined` resumes with `undefined`). */
|
|
234
232
|
complete(token: string, result?: unknown): Promise<void>;
|
|
235
233
|
/** Fail a deferred activity by token; the error is thrown into its workflow. */
|
|
@@ -259,7 +257,6 @@ export interface WeftClient {
|
|
|
259
257
|
* returned handle's `result()` to its output type. Without augmentation the
|
|
260
258
|
* permissive string-name overload applies, so the client stays usable with
|
|
261
259
|
* plain string names and no hard dependency on codegen.
|
|
262
|
-
*
|
|
263
260
|
* Pass `options.idempotencyKey` for at-most-once starts: a repeated key returns
|
|
264
261
|
* a handle to the existing run rather than starting a second. Conflicts (a
|
|
265
262
|
* duplicate `id`, or a key whose run was purged) are transport-dependent:
|
|
@@ -339,8 +336,8 @@ export interface WeftClient {
|
|
|
339
336
|
resumeSchedule(id: string): Promise<void>;
|
|
340
337
|
/** Cancel a recurring schedule. */
|
|
341
338
|
cancelSchedule(id: string): Promise<void>;
|
|
342
|
-
/** Update a recurring schedule's
|
|
343
|
-
updateSchedule(id: string, newSpec: string | ScheduleSpec): Promise<void>;
|
|
339
|
+
/** Update a recurring schedule's cadence and optional mutable schedule settings. */
|
|
340
|
+
updateSchedule(id: string, newSpec: string | ScheduleSpec, options?: ScheduleEdit): Promise<void>;
|
|
344
341
|
/** Send a named signal to a workflow. */
|
|
345
342
|
signal(id: string, name: SignalDefinition): Promise<void>;
|
|
346
343
|
signal<TInput>(id: string, name: SignalDefinition<TInput>, payload: TInput, options?: SignalDeliveryOptions): Promise<void>;
|
|
@@ -433,11 +430,12 @@ export interface WeftClient {
|
|
|
433
430
|
/**
|
|
434
431
|
* Typed low-level accessor for the full operation catalog.
|
|
435
432
|
*
|
|
436
|
-
* Every
|
|
437
|
-
*
|
|
438
|
-
*
|
|
439
|
-
*
|
|
440
|
-
*
|
|
433
|
+
* Every unary JSON-RPC operation and ordinary schema-shaped REST-only
|
|
434
|
+
* operation is reachable as `client.operations['weft.<op>']`, including
|
|
435
|
+
* server operations the ergonomic surface does not curate (workers, task
|
|
436
|
+
* queues, task diagnostics, system lease/metrics/registry, checkpoints). Binary
|
|
437
|
+
* and streaming raw-storage routes use {@link storage} instead. New compatible
|
|
438
|
+
* operations appear here when the snapshot regenerates.
|
|
441
439
|
*
|
|
442
440
|
* @example
|
|
443
441
|
* ```ts
|
|
@@ -450,11 +448,13 @@ export interface WeftClient {
|
|
|
450
448
|
* void metrics;
|
|
451
449
|
* ```
|
|
452
450
|
*/
|
|
453
|
-
readonly operations:
|
|
451
|
+
readonly operations: ClientOperations;
|
|
452
|
+
/** Raw storage administration with byte values and streaming scans. */
|
|
453
|
+
readonly storage: WeftClientStorage;
|
|
454
454
|
/**
|
|
455
455
|
* Invoke a single catalog operation by name, with its input and output typed
|
|
456
456
|
* from the generated catalog. Equivalent to `client.operations[name](input)`
|
|
457
457
|
* but ergonomic when the operation name is known dynamically.
|
|
458
458
|
*/
|
|
459
|
-
call<Name extends
|
|
459
|
+
call<Name extends ClientOperationName>(name: Name, input: ClientOperationTypes[Name]['input']): Promise<ClientOperationTypes[Name]['output']>;
|
|
460
460
|
}
|