@voyantjs/workflows 0.37.1 → 0.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -35,6 +35,12 @@ export const sendBookingReminders = workflow({
35
35
  `X-Voyant-Dispatch-Auth` header. Wires into the orchestrator's
36
36
  `sign` hook and the handler's `verifyRequest` hook with a shared
37
37
  secret.
38
+ - `@voyantjs/workflows/bindings` — runtime binding types and `env`
39
+ shim for workflow code that reads platform bindings.
40
+ - `@voyantjs/workflows/config` — `defineConfig` and `voyant.config.ts`
41
+ types.
42
+ - `@voyantjs/workflows/errors` — typed user/runtime errors
43
+ (`FatalError`, `RetryableError`, `TimeoutError`, and related classes).
38
44
  - `@voyantjs/workflows/protocol` — wire-protocol types shared with the
39
45
  orchestrator.
40
46
 
@@ -43,4 +49,3 @@ export const sendBookingReminders = workflow({
43
49
  - [`docs/sdk-surface.md`](../../docs/sdk-surface.md) — locked API surface.
44
50
  - [`docs/design.md`](../../docs/design.md) — architecture and rationale.
45
51
  - [`docs/runtime-protocol.md`](../../docs/runtime-protocol.md) — wire protocol.
46
-
@@ -0,0 +1,119 @@
1
+ export interface Env {
2
+ [key: string]: Binding;
3
+ }
4
+ export type Binding = D1Database | R2Bucket | KVNamespace | Queue<unknown> | string;
5
+ export interface D1Database {
6
+ prepare(sql: string): D1PreparedStatement;
7
+ batch(statements: D1PreparedStatement[]): Promise<D1Result[]>;
8
+ exec(sql: string): Promise<D1ExecResult>;
9
+ }
10
+ export interface D1PreparedStatement {
11
+ bind(...values: unknown[]): D1PreparedStatement;
12
+ first<T = unknown>(column?: string): Promise<T | null>;
13
+ run(): Promise<D1Result>;
14
+ all<T = unknown>(): Promise<{
15
+ results: T[];
16
+ meta: D1Meta;
17
+ }>;
18
+ /** Per-step-invocation read cache. */
19
+ memoize(): D1PreparedStatement;
20
+ }
21
+ export interface D1Result {
22
+ success: boolean;
23
+ meta: D1Meta;
24
+ results?: unknown[];
25
+ }
26
+ export interface D1ExecResult {
27
+ count: number;
28
+ duration: number;
29
+ }
30
+ export interface D1Meta {
31
+ duration: number;
32
+ rows_read: number;
33
+ rows_written: number;
34
+ }
35
+ export interface R2Bucket {
36
+ get(key: string, opts?: R2GetOptions): Promise<R2Object | null>;
37
+ put(key: string, value: R2PutBody, opts?: R2PutOptions): Promise<R2Object>;
38
+ delete(keys: string | string[]): Promise<void>;
39
+ list(opts?: R2ListOptions): Promise<R2Objects>;
40
+ head(key: string): Promise<R2Object | null>;
41
+ }
42
+ export interface R2GetOptions {
43
+ range?: {
44
+ offset?: number;
45
+ length?: number;
46
+ };
47
+ onlyIf?: {
48
+ etagMatches?: string;
49
+ };
50
+ }
51
+ export interface R2PutOptions {
52
+ httpMetadata?: Record<string, string>;
53
+ customMetadata?: Record<string, string>;
54
+ }
55
+ export type R2PutBody = ReadableStream | ArrayBuffer | string;
56
+ export interface R2Object {
57
+ key: string;
58
+ size: number;
59
+ etag: string;
60
+ httpMetadata?: Record<string, string>;
61
+ customMetadata?: Record<string, string>;
62
+ body?: ReadableStream;
63
+ arrayBuffer(): Promise<ArrayBuffer>;
64
+ text(): Promise<string>;
65
+ json<T = unknown>(): Promise<T>;
66
+ }
67
+ export interface R2ListOptions {
68
+ prefix?: string;
69
+ cursor?: string;
70
+ limit?: number;
71
+ }
72
+ export interface R2Objects {
73
+ objects: R2Object[];
74
+ truncated: boolean;
75
+ cursor?: string;
76
+ }
77
+ export interface KVNamespace {
78
+ get<T = string>(key: string, opts?: KVGetOptions<T>): Promise<T | null>;
79
+ put(key: string, value: string | ArrayBuffer, opts?: KVPutOptions): Promise<void>;
80
+ delete(key: string): Promise<void>;
81
+ list(opts?: KVListOptions): Promise<KVList>;
82
+ }
83
+ export interface KVGetOptions<T> {
84
+ type?: T extends string ? "text" : "json" | "arrayBuffer" | "stream";
85
+ }
86
+ export interface KVPutOptions {
87
+ expiration?: number;
88
+ expirationTtl?: number;
89
+ metadata?: Record<string, unknown>;
90
+ }
91
+ export interface KVListOptions {
92
+ prefix?: string;
93
+ cursor?: string;
94
+ limit?: number;
95
+ }
96
+ export interface KVList {
97
+ keys: {
98
+ name: string;
99
+ expiration?: number;
100
+ metadata?: unknown;
101
+ }[];
102
+ list_complete: boolean;
103
+ cursor?: string;
104
+ }
105
+ export interface Queue<T> {
106
+ send(message: T, opts?: {
107
+ delaySeconds?: number;
108
+ }): Promise<void>;
109
+ sendBatch(messages: readonly T[]): Promise<void>;
110
+ }
111
+ /**
112
+ * The environment object tenant code reads bindings from.
113
+ *
114
+ * On the edge runtime, this is a pass-through to the tenant worker's
115
+ * `env` parameter (CF Workers). On the container runtime, the
116
+ * platform injects HTTP-based clients that mimic the shapes above.
117
+ */
118
+ export declare const env: Env;
119
+ //# sourceMappingURL=bindings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bindings.d.ts","sourceRoot":"","sources":["../src/bindings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ // @voyantjs/workflows/bindings
2
+ //
3
+ // Runtime binding shim. Edge runtime passes through to native CF bindings;
4
+ // container runtime makes authenticated HTTPS calls to CF's per-binding APIs.
5
+ //
6
+ // Contract defined in docs/sdk-surface.md §9 and docs/design.md §5.2.
7
+ /**
8
+ * The environment object tenant code reads bindings from.
9
+ *
10
+ * On the edge runtime, this is a pass-through to the tenant worker's
11
+ * `env` parameter (CF Workers). On the container runtime, the
12
+ * platform injects HTTP-based clients that mimic the shapes above.
13
+ */
14
+ export const env = new Proxy({}, {
15
+ get(_, key) {
16
+ throw new Error(`@voyantjs/workflows/bindings: env.${key} was accessed outside a workflow / step body. ` +
17
+ `Bindings are injected by the runtime — see docs/sdk-surface.md §9.`);
18
+ },
19
+ });
@@ -0,0 +1,93 @@
1
+ export type Duration = number | `${number}${"ms" | "s" | "m" | "h" | "d" | "w"}`;
2
+ /** Cloudflare Container instance types — see `@voyantjs/workflows` for the size table. */
3
+ export type MachineType = "lite" | "basic" | "standard-1" | "standard-2" | "standard-3" | "standard-4" | (string & {});
4
+ export type EnvironmentName = "production" | "preview" | "development";
5
+ export type MeterKey = "edgeCpuMs" | "containerSeconds" | "warmSlotHours" | "runCount" | "activeScheduleHours" | "payloadStorageGbHour" | "retentionRunMonths";
6
+ export type BindingDeclaration = {
7
+ type: "d1";
8
+ name: string;
9
+ } | {
10
+ type: "r2";
11
+ name: string;
12
+ } | {
13
+ type: "kv";
14
+ name: string;
15
+ } | {
16
+ type: "queue";
17
+ name: string;
18
+ };
19
+ export interface EnvironmentConfig {
20
+ customDomain?: string;
21
+ }
22
+ export interface RetryPolicy {
23
+ max?: number;
24
+ backoff?: "exponential" | "linear" | "fixed";
25
+ initial?: Duration;
26
+ maxDelay?: Duration;
27
+ }
28
+ export interface BuildExtension {
29
+ name: string;
30
+ /** Open-ended hook surface; each extension defines its own contract. */
31
+ [key: string]: unknown;
32
+ }
33
+ export interface Instrumentation {
34
+ name: string;
35
+ [key: string]: unknown;
36
+ }
37
+ export interface WorkflowsConfig {
38
+ dirs?: string[];
39
+ defaults?: {
40
+ retries?: RetryPolicy;
41
+ timeout?: Duration;
42
+ timezone?: string;
43
+ machine?: MachineType;
44
+ concurrency?: {
45
+ strategy?: "queue" | "cancel-in-progress" | "cancel-newest" | "round-robin";
46
+ };
47
+ };
48
+ containerPool?: {
49
+ defaultMachine?: MachineType;
50
+ maxConcurrency?: number;
51
+ warmPoolSize?: Partial<Record<EnvironmentName, number>>;
52
+ evictionTtl?: Duration;
53
+ perPodConcurrency?: number;
54
+ scaleOutPolicy?: "none" | "onDemand";
55
+ preWarmStrategy?: "onFirstRequest" | "onDeploy";
56
+ };
57
+ build?: {
58
+ extensions?: BuildExtension[];
59
+ defineEnv?: Record<string, string>;
60
+ };
61
+ instrumentations?: Instrumentation[];
62
+ dev?: {
63
+ port?: number;
64
+ preservation?: "smart" | "always" | "never";
65
+ simulateEnvironment?: EnvironmentName;
66
+ };
67
+ billing?: {
68
+ caps?: {
69
+ monthly?: Partial<Record<MeterKey, number>>;
70
+ action?: "hard-stop" | "soft-notify";
71
+ perEnvironment?: Partial<Record<EnvironmentName, {
72
+ monthly?: Partial<Record<MeterKey, number>>;
73
+ }>>;
74
+ };
75
+ };
76
+ versioning?: {
77
+ retireAfter?: Duration;
78
+ onSunset?: "cancel" | "migrate" | "extend";
79
+ sunsetNoticePeriod?: Duration;
80
+ };
81
+ }
82
+ export interface VoyantConfig {
83
+ projectId: string;
84
+ entry: {
85
+ worker: string;
86
+ container?: string;
87
+ };
88
+ environments: Record<EnvironmentName, EnvironmentConfig>;
89
+ bindings: Record<string, BindingDeclaration>;
90
+ workflows?: WorkflowsConfig;
91
+ }
92
+ export declare function defineConfig(config: VoyantConfig): VoyantConfig;
93
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,GAAG,MAAM,GAAG,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,CAAA;AAEhF,0FAA0F;AAC1F,MAAM,MAAM,WAAW,GACnB,MAAM,GACN,OAAO,GACP,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;AAEjB,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,SAAS,GAAG,aAAa,CAAA;AAEtE,MAAM,MAAM,QAAQ,GAChB,WAAW,GACX,kBAAkB,GAClB,eAAe,GACf,UAAU,GACV,qBAAqB,GACrB,sBAAsB,GACtB,oBAAoB,CAAA;AAExB,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEnC,MAAM,WAAW,iBAAiB;IAChC,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,aAAa,GAAG,QAAQ,GAAG,OAAO,CAAA;IAC5C,OAAO,CAAC,EAAE,QAAQ,CAAA;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,wEAAwE;IACxE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,QAAQ,CAAC,EAAE;QACT,OAAO,CAAC,EAAE,WAAW,CAAA;QACrB,OAAO,CAAC,EAAE,QAAQ,CAAA;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,OAAO,CAAC,EAAE,WAAW,CAAA;QACrB,WAAW,CAAC,EAAE;YAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,oBAAoB,GAAG,eAAe,GAAG,aAAa,CAAA;SAAE,CAAA;KAC9F,CAAA;IACD,aAAa,CAAC,EAAE;QACd,cAAc,CAAC,EAAE,WAAW,CAAA;QAC5B,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB,YAAY,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAA;QACvD,WAAW,CAAC,EAAE,QAAQ,CAAA;QACtB,iBAAiB,CAAC,EAAE,MAAM,CAAA;QAC1B,cAAc,CAAC,EAAE,MAAM,GAAG,UAAU,CAAA;QACpC,eAAe,CAAC,EAAE,gBAAgB,GAAG,UAAU,CAAA;KAChD,CAAA;IACD,KAAK,CAAC,EAAE;QACN,UAAU,CAAC,EAAE,cAAc,EAAE,CAAA;QAC7B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KACnC,CAAA;IACD,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAA;IACpC,GAAG,CAAC,EAAE;QACJ,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,YAAY,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAA;QAC3C,mBAAmB,CAAC,EAAE,eAAe,CAAA;KACtC,CAAA;IACD,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE;YACL,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAA;YAC3C,MAAM,CAAC,EAAE,WAAW,GAAG,aAAa,CAAA;YACpC,cAAc,CAAC,EAAE,OAAO,CACtB,MAAM,CAAC,eAAe,EAAE;gBAAE,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAA;aAAE,CAAC,CACzE,CAAA;SACF,CAAA;KACF,CAAA;IACD,UAAU,CAAC,EAAE;QACX,WAAW,CAAC,EAAE,QAAQ,CAAA;QACtB,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAA;QAC1C,kBAAkB,CAAC,EAAE,QAAQ,CAAA;KAC9B,CAAA;CACF;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE;QACL,MAAM,EAAE,MAAM,CAAA;QACd,SAAS,CAAC,EAAE,MAAM,CAAA;KACnB,CAAA;IACD,YAAY,EAAE,MAAM,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAA;IACxD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;IAC5C,SAAS,CAAC,EAAE,eAAe,CAAA;CAC5B;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAE/D"}
package/dist/config.js ADDED
@@ -0,0 +1,7 @@
1
+ // @voyantjs/workflows/config
2
+ //
3
+ // Types and `defineConfig` helper for `voyant.config.ts`.
4
+ // Contract defined in docs/sdk-surface.md §10 and docs/design.md §5.4.3.
5
+ export function defineConfig(config) {
6
+ return config;
7
+ }
@@ -0,0 +1,58 @@
1
+ export type ErrorCategory = "USER_ERROR" | "RUNTIME_ERROR";
2
+ export declare abstract class VoyantError extends Error {
3
+ readonly code: string;
4
+ readonly category: ErrorCategory;
5
+ constructor(message: string, opts: {
6
+ code: string;
7
+ category: ErrorCategory;
8
+ cause?: unknown;
9
+ });
10
+ }
11
+ export declare class FatalError extends VoyantError {
12
+ constructor(message: string, opts?: {
13
+ cause?: unknown;
14
+ code?: string;
15
+ });
16
+ }
17
+ export type RetryAfter = string | number | Date;
18
+ export declare class RetryableError extends VoyantError {
19
+ readonly retryAfter?: RetryAfter;
20
+ constructor(message: string, opts?: {
21
+ retryAfter?: RetryAfter;
22
+ cause?: unknown;
23
+ code?: string;
24
+ });
25
+ }
26
+ export declare class TimeoutError extends VoyantError {
27
+ constructor(message: string, opts?: {
28
+ cause?: unknown;
29
+ });
30
+ }
31
+ export declare class HookConflictError extends VoyantError {
32
+ readonly tokenId: string;
33
+ constructor(tokenId: string, opts?: {
34
+ cause?: unknown;
35
+ });
36
+ }
37
+ export declare class QuotaExceededError extends VoyantError {
38
+ readonly meter: string;
39
+ readonly limit: number;
40
+ readonly environment: "production" | "preview" | "development";
41
+ constructor(opts: {
42
+ meter: string;
43
+ limit: number;
44
+ environment: "production" | "preview" | "development";
45
+ cause?: unknown;
46
+ });
47
+ }
48
+ export interface ValidationIssue {
49
+ path: string[];
50
+ message: string;
51
+ }
52
+ export declare class ValidationError extends VoyantError {
53
+ readonly issues: ValidationIssue[];
54
+ constructor(issues: ValidationIssue[], opts?: {
55
+ cause?: unknown;
56
+ });
57
+ }
58
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,eAAe,CAAA;AAE1D,8BAAsB,WAAY,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAA;gBAG9B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAA;QACZ,QAAQ,EAAE,aAAa,CAAA;QACvB,KAAK,CAAC,EAAE,OAAO,CAAA;KAChB;CAOJ;AAED,qBAAa,UAAW,SAAQ,WAAW;gBAC7B,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE;CAOvE;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;AAE/C,qBAAa,cAAe,SAAQ,WAAW;IAC7C,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAA;gBAEpB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,UAAU,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE;CAQhG;AAED,qBAAa,YAAa,SAAQ,WAAW;gBAC/B,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAGxD;AAED,qBAAa,iBAAkB,SAAQ,WAAW;IAChD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;gBAEZ,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAQxD;AAED,qBAAa,kBAAmB,SAAQ,WAAW;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,WAAW,EAAE,YAAY,GAAG,SAAS,GAAG,aAAa,CAAA;gBAElD,IAAI,EAAE;QAChB,KAAK,EAAE,MAAM,CAAA;QACb,KAAK,EAAE,MAAM,CAAA;QACb,WAAW,EAAE,YAAY,GAAG,SAAS,GAAG,aAAa,CAAA;QACrD,KAAK,CAAC,EAAE,OAAO,CAAA;KAChB;CAUF;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,QAAQ,CAAC,MAAM,EAAE,eAAe,EAAE,CAAA;gBAEtB,MAAM,EAAE,eAAe,EAAE,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAQlE"}
package/dist/errors.js ADDED
@@ -0,0 +1,76 @@
1
+ // @voyantjs/workflows/errors
2
+ //
3
+ // Typed error classes used across the Voyant Workflows SDK.
4
+ // Contract defined in docs/sdk-surface.md §7.
5
+ export class VoyantError extends Error {
6
+ code;
7
+ category;
8
+ constructor(message, opts) {
9
+ super(message, { cause: opts.cause });
10
+ this.name = new.target.name;
11
+ this.code = opts.code;
12
+ this.category = opts.category;
13
+ }
14
+ }
15
+ export class FatalError extends VoyantError {
16
+ constructor(message, opts) {
17
+ super(message, {
18
+ code: opts?.code ?? "FATAL",
19
+ category: "USER_ERROR",
20
+ cause: opts?.cause,
21
+ });
22
+ }
23
+ }
24
+ export class RetryableError extends VoyantError {
25
+ retryAfter;
26
+ constructor(message, opts) {
27
+ super(message, {
28
+ code: opts?.code ?? "RETRYABLE",
29
+ category: "USER_ERROR",
30
+ cause: opts?.cause,
31
+ });
32
+ this.retryAfter = opts?.retryAfter;
33
+ }
34
+ }
35
+ export class TimeoutError extends VoyantError {
36
+ constructor(message, opts) {
37
+ super(message, { code: "TIMEOUT", category: "RUNTIME_ERROR", cause: opts?.cause });
38
+ }
39
+ }
40
+ export class HookConflictError extends VoyantError {
41
+ tokenId;
42
+ constructor(tokenId, opts) {
43
+ super(`hook token already resolved: ${tokenId}`, {
44
+ code: "HOOK_CONFLICT",
45
+ category: "RUNTIME_ERROR",
46
+ cause: opts?.cause,
47
+ });
48
+ this.tokenId = tokenId;
49
+ }
50
+ }
51
+ export class QuotaExceededError extends VoyantError {
52
+ meter;
53
+ limit;
54
+ environment;
55
+ constructor(opts) {
56
+ super(`quota exceeded for ${opts.meter} (limit ${opts.limit}) in ${opts.environment}`, {
57
+ code: "QUOTA_EXCEEDED",
58
+ category: "RUNTIME_ERROR",
59
+ cause: opts.cause,
60
+ });
61
+ this.meter = opts.meter;
62
+ this.limit = opts.limit;
63
+ this.environment = opts.environment;
64
+ }
65
+ }
66
+ export class ValidationError extends VoyantError {
67
+ issues;
68
+ constructor(issues, opts) {
69
+ super(`validation failed with ${issues.length} issue${issues.length === 1 ? "" : "s"}`, {
70
+ code: "VALIDATION",
71
+ category: "USER_ERROR",
72
+ cause: opts?.cause,
73
+ });
74
+ this.issues = issues;
75
+ }
76
+ }
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { FatalError, HookConflictError, QuotaExceededError, RetryableError, TimeoutError, ValidationError, } from "@voyantjs/workflows-errors";
2
1
  export * from "./conditions.js";
2
+ export { FatalError, HookConflictError, QuotaExceededError, RetryableError, TimeoutError, ValidationError, } from "./errors.js";
3
3
  export * from "./trigger.js";
4
4
  export * from "./types.js";
5
5
  export * from "./workflow.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,eAAe,GAChB,MAAM,4BAA4B,CAAA;AACnC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,cAAc,iBAAiB,CAAA;AAC/B,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,eAAe,GAChB,MAAM,aAAa,CAAA;AACpB,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA"}
package/dist/index.js CHANGED
@@ -3,8 +3,8 @@
3
3
  // Authoring SDK for Voyant Workflows. Full contract in:
4
4
  // docs/sdk-surface.md §2–§8
5
5
  // docs/design.md §3–§4
6
- export { FatalError, HookConflictError, QuotaExceededError, RetryableError, TimeoutError, ValidationError, } from "@voyantjs/workflows-errors";
7
6
  export * from "./conditions.js";
7
+ export { FatalError, HookConflictError, QuotaExceededError, RetryableError, TimeoutError, ValidationError, } from "./errors.js";
8
8
  export * from "./trigger.js";
9
9
  export * from "./types.js";
10
10
  export * from "./workflow.js";
@@ -1,4 +1,4 @@
1
- // Internal runtime signal errors. Distinct from user-facing `@voyantjs/workflows-errors`:
1
+ // Internal runtime signal errors. Distinct from user-facing `@voyantjs/workflows/errors`:
2
2
  // these are thrown inside the executor to unwind the workflow body on
3
3
  // waitpoint yield or run cancellation. They must not be caught by user
4
4
  // code (the executor re-throws if it observes one being swallowed).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyantjs/workflows",
3
- "version": "0.37.1",
3
+ "version": "0.38.0",
4
4
  "description": "Authoring SDK for Voyant Workflows — durable, step-based orchestrations for Voyant Cloud.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -31,6 +31,18 @@
31
31
  "types": "./dist/auth/index.d.ts",
32
32
  "import": "./dist/auth/index.js"
33
33
  },
34
+ "./bindings": {
35
+ "types": "./dist/bindings.d.ts",
36
+ "import": "./dist/bindings.js"
37
+ },
38
+ "./config": {
39
+ "types": "./dist/config.d.ts",
40
+ "import": "./dist/config.js"
41
+ },
42
+ "./errors": {
43
+ "types": "./dist/errors.d.ts",
44
+ "import": "./dist/errors.js"
45
+ },
34
46
  "./rate-limit": {
35
47
  "types": "./dist/rate-limit/index.d.ts",
36
48
  "import": "./dist/rate-limit/index.js"
@@ -58,8 +70,7 @@
58
70
  "NOTICE"
59
71
  ],
60
72
  "dependencies": {
61
- "zod": "^3.23.8",
62
- "@voyantjs/workflows-errors": "0.37.1"
73
+ "zod": "^3.23.8"
63
74
  },
64
75
  "devDependencies": {
65
76
  "@types/node": "^20.12.0",
@@ -0,0 +1,135 @@
1
+ // @voyantjs/workflows/bindings
2
+ //
3
+ // Runtime binding shim. Edge runtime passes through to native CF bindings;
4
+ // container runtime makes authenticated HTTPS calls to CF's per-binding APIs.
5
+ //
6
+ // Contract defined in docs/sdk-surface.md §9 and docs/design.md §5.2.
7
+
8
+ // Types intentionally mirror Cloudflare's native binding shapes so the
9
+ // same code runs on edge and container runtimes. Runtime behavior is
10
+ // provided by the platform (native bindings on Workers; an HTTPS shim
11
+ // on the container runtime) — this package is the shared type surface.
12
+
13
+ export interface Env {
14
+ [key: string]: Binding
15
+ }
16
+
17
+ export type Binding = D1Database | R2Bucket | KVNamespace | Queue<unknown> | string // secrets
18
+
19
+ export interface D1Database {
20
+ prepare(sql: string): D1PreparedStatement
21
+ batch(statements: D1PreparedStatement[]): Promise<D1Result[]>
22
+ exec(sql: string): Promise<D1ExecResult>
23
+ }
24
+
25
+ export interface D1PreparedStatement {
26
+ bind(...values: unknown[]): D1PreparedStatement
27
+ first<T = unknown>(column?: string): Promise<T | null>
28
+ run(): Promise<D1Result>
29
+ all<T = unknown>(): Promise<{ results: T[]; meta: D1Meta }>
30
+ /** Per-step-invocation read cache. */
31
+ memoize(): D1PreparedStatement
32
+ }
33
+
34
+ export interface D1Result {
35
+ success: boolean
36
+ meta: D1Meta
37
+ results?: unknown[]
38
+ }
39
+
40
+ export interface D1ExecResult {
41
+ count: number
42
+ duration: number
43
+ }
44
+
45
+ export interface D1Meta {
46
+ duration: number
47
+ rows_read: number
48
+ rows_written: number
49
+ }
50
+
51
+ export interface R2Bucket {
52
+ get(key: string, opts?: R2GetOptions): Promise<R2Object | null>
53
+ put(key: string, value: R2PutBody, opts?: R2PutOptions): Promise<R2Object>
54
+ delete(keys: string | string[]): Promise<void>
55
+ list(opts?: R2ListOptions): Promise<R2Objects>
56
+ head(key: string): Promise<R2Object | null>
57
+ }
58
+
59
+ export interface R2GetOptions {
60
+ range?: { offset?: number; length?: number }
61
+ onlyIf?: { etagMatches?: string }
62
+ }
63
+ export interface R2PutOptions {
64
+ httpMetadata?: Record<string, string>
65
+ customMetadata?: Record<string, string>
66
+ }
67
+ export type R2PutBody = ReadableStream | ArrayBuffer | string
68
+ export interface R2Object {
69
+ key: string
70
+ size: number
71
+ etag: string
72
+ httpMetadata?: Record<string, string>
73
+ customMetadata?: Record<string, string>
74
+ body?: ReadableStream
75
+ arrayBuffer(): Promise<ArrayBuffer>
76
+ text(): Promise<string>
77
+ json<T = unknown>(): Promise<T>
78
+ }
79
+ export interface R2ListOptions {
80
+ prefix?: string
81
+ cursor?: string
82
+ limit?: number
83
+ }
84
+ export interface R2Objects {
85
+ objects: R2Object[]
86
+ truncated: boolean
87
+ cursor?: string
88
+ }
89
+
90
+ export interface KVNamespace {
91
+ get<T = string>(key: string, opts?: KVGetOptions<T>): Promise<T | null>
92
+ put(key: string, value: string | ArrayBuffer, opts?: KVPutOptions): Promise<void>
93
+ delete(key: string): Promise<void>
94
+ list(opts?: KVListOptions): Promise<KVList>
95
+ }
96
+
97
+ export interface KVGetOptions<T> {
98
+ type?: T extends string ? "text" : "json" | "arrayBuffer" | "stream"
99
+ }
100
+ export interface KVPutOptions {
101
+ expiration?: number
102
+ expirationTtl?: number
103
+ metadata?: Record<string, unknown>
104
+ }
105
+ export interface KVListOptions {
106
+ prefix?: string
107
+ cursor?: string
108
+ limit?: number
109
+ }
110
+ export interface KVList {
111
+ keys: { name: string; expiration?: number; metadata?: unknown }[]
112
+ list_complete: boolean
113
+ cursor?: string
114
+ }
115
+
116
+ export interface Queue<T> {
117
+ send(message: T, opts?: { delaySeconds?: number }): Promise<void>
118
+ sendBatch(messages: readonly T[]): Promise<void>
119
+ }
120
+
121
+ /**
122
+ * The environment object tenant code reads bindings from.
123
+ *
124
+ * On the edge runtime, this is a pass-through to the tenant worker's
125
+ * `env` parameter (CF Workers). On the container runtime, the
126
+ * platform injects HTTP-based clients that mimic the shapes above.
127
+ */
128
+ export const env: Env = new Proxy({} as Env, {
129
+ get(_, key: string): Binding {
130
+ throw new Error(
131
+ `@voyantjs/workflows/bindings: env.${key} was accessed outside a workflow / step body. ` +
132
+ `Bindings are injected by the runtime — see docs/sdk-surface.md §9.`,
133
+ )
134
+ },
135
+ })
package/src/config.ts ADDED
@@ -0,0 +1,114 @@
1
+ // @voyantjs/workflows/config
2
+ //
3
+ // Types and `defineConfig` helper for `voyant.config.ts`.
4
+ // Contract defined in docs/sdk-surface.md §10 and docs/design.md §5.4.3.
5
+
6
+ export type Duration = number | `${number}${"ms" | "s" | "m" | "h" | "d" | "w"}`
7
+
8
+ /** Cloudflare Container instance types — see `@voyantjs/workflows` for the size table. */
9
+ export type MachineType =
10
+ | "lite"
11
+ | "basic"
12
+ | "standard-1"
13
+ | "standard-2"
14
+ | "standard-3"
15
+ | "standard-4"
16
+ | (string & {})
17
+
18
+ export type EnvironmentName = "production" | "preview" | "development"
19
+
20
+ export type MeterKey =
21
+ | "edgeCpuMs"
22
+ | "containerSeconds"
23
+ | "warmSlotHours"
24
+ | "runCount"
25
+ | "activeScheduleHours"
26
+ | "payloadStorageGbHour"
27
+ | "retentionRunMonths"
28
+
29
+ export type BindingDeclaration =
30
+ | { type: "d1"; name: string }
31
+ | { type: "r2"; name: string }
32
+ | { type: "kv"; name: string }
33
+ | { type: "queue"; name: string }
34
+
35
+ export interface EnvironmentConfig {
36
+ customDomain?: string
37
+ }
38
+
39
+ export interface RetryPolicy {
40
+ max?: number
41
+ backoff?: "exponential" | "linear" | "fixed"
42
+ initial?: Duration
43
+ maxDelay?: Duration
44
+ }
45
+
46
+ export interface BuildExtension {
47
+ name: string
48
+ /** Open-ended hook surface; each extension defines its own contract. */
49
+ [key: string]: unknown
50
+ }
51
+
52
+ export interface Instrumentation {
53
+ name: string
54
+ [key: string]: unknown
55
+ }
56
+
57
+ export interface WorkflowsConfig {
58
+ dirs?: string[]
59
+ defaults?: {
60
+ retries?: RetryPolicy
61
+ timeout?: Duration
62
+ timezone?: string
63
+ machine?: MachineType
64
+ concurrency?: { strategy?: "queue" | "cancel-in-progress" | "cancel-newest" | "round-robin" }
65
+ }
66
+ containerPool?: {
67
+ defaultMachine?: MachineType
68
+ maxConcurrency?: number
69
+ warmPoolSize?: Partial<Record<EnvironmentName, number>>
70
+ evictionTtl?: Duration
71
+ perPodConcurrency?: number
72
+ scaleOutPolicy?: "none" | "onDemand"
73
+ preWarmStrategy?: "onFirstRequest" | "onDeploy"
74
+ }
75
+ build?: {
76
+ extensions?: BuildExtension[]
77
+ defineEnv?: Record<string, string>
78
+ }
79
+ instrumentations?: Instrumentation[]
80
+ dev?: {
81
+ port?: number
82
+ preservation?: "smart" | "always" | "never"
83
+ simulateEnvironment?: EnvironmentName
84
+ }
85
+ billing?: {
86
+ caps?: {
87
+ monthly?: Partial<Record<MeterKey, number>>
88
+ action?: "hard-stop" | "soft-notify"
89
+ perEnvironment?: Partial<
90
+ Record<EnvironmentName, { monthly?: Partial<Record<MeterKey, number>> }>
91
+ >
92
+ }
93
+ }
94
+ versioning?: {
95
+ retireAfter?: Duration
96
+ onSunset?: "cancel" | "migrate" | "extend"
97
+ sunsetNoticePeriod?: Duration
98
+ }
99
+ }
100
+
101
+ export interface VoyantConfig {
102
+ projectId: string
103
+ entry: {
104
+ worker: string
105
+ container?: string
106
+ }
107
+ environments: Record<EnvironmentName, EnvironmentConfig>
108
+ bindings: Record<string, BindingDeclaration>
109
+ workflows?: WorkflowsConfig
110
+ }
111
+
112
+ export function defineConfig(config: VoyantConfig): VoyantConfig {
113
+ return config
114
+ }
package/src/errors.ts ADDED
@@ -0,0 +1,109 @@
1
+ // @voyantjs/workflows/errors
2
+ //
3
+ // Typed error classes used across the Voyant Workflows SDK.
4
+ // Contract defined in docs/sdk-surface.md §7.
5
+
6
+ export type ErrorCategory = "USER_ERROR" | "RUNTIME_ERROR"
7
+
8
+ export abstract class VoyantError extends Error {
9
+ readonly code: string
10
+ readonly category: ErrorCategory
11
+
12
+ constructor(
13
+ message: string,
14
+ opts: {
15
+ code: string
16
+ category: ErrorCategory
17
+ cause?: unknown
18
+ },
19
+ ) {
20
+ super(message, { cause: opts.cause })
21
+ this.name = new.target.name
22
+ this.code = opts.code
23
+ this.category = opts.category
24
+ }
25
+ }
26
+
27
+ export class FatalError extends VoyantError {
28
+ constructor(message: string, opts?: { cause?: unknown; code?: string }) {
29
+ super(message, {
30
+ code: opts?.code ?? "FATAL",
31
+ category: "USER_ERROR",
32
+ cause: opts?.cause,
33
+ })
34
+ }
35
+ }
36
+
37
+ export type RetryAfter = string | number | Date
38
+
39
+ export class RetryableError extends VoyantError {
40
+ readonly retryAfter?: RetryAfter
41
+
42
+ constructor(message: string, opts?: { retryAfter?: RetryAfter; cause?: unknown; code?: string }) {
43
+ super(message, {
44
+ code: opts?.code ?? "RETRYABLE",
45
+ category: "USER_ERROR",
46
+ cause: opts?.cause,
47
+ })
48
+ this.retryAfter = opts?.retryAfter
49
+ }
50
+ }
51
+
52
+ export class TimeoutError extends VoyantError {
53
+ constructor(message: string, opts?: { cause?: unknown }) {
54
+ super(message, { code: "TIMEOUT", category: "RUNTIME_ERROR", cause: opts?.cause })
55
+ }
56
+ }
57
+
58
+ export class HookConflictError extends VoyantError {
59
+ readonly tokenId: string
60
+
61
+ constructor(tokenId: string, opts?: { cause?: unknown }) {
62
+ super(`hook token already resolved: ${tokenId}`, {
63
+ code: "HOOK_CONFLICT",
64
+ category: "RUNTIME_ERROR",
65
+ cause: opts?.cause,
66
+ })
67
+ this.tokenId = tokenId
68
+ }
69
+ }
70
+
71
+ export class QuotaExceededError extends VoyantError {
72
+ readonly meter: string
73
+ readonly limit: number
74
+ readonly environment: "production" | "preview" | "development"
75
+
76
+ constructor(opts: {
77
+ meter: string
78
+ limit: number
79
+ environment: "production" | "preview" | "development"
80
+ cause?: unknown
81
+ }) {
82
+ super(`quota exceeded for ${opts.meter} (limit ${opts.limit}) in ${opts.environment}`, {
83
+ code: "QUOTA_EXCEEDED",
84
+ category: "RUNTIME_ERROR",
85
+ cause: opts.cause,
86
+ })
87
+ this.meter = opts.meter
88
+ this.limit = opts.limit
89
+ this.environment = opts.environment
90
+ }
91
+ }
92
+
93
+ export interface ValidationIssue {
94
+ path: string[]
95
+ message: string
96
+ }
97
+
98
+ export class ValidationError extends VoyantError {
99
+ readonly issues: ValidationIssue[]
100
+
101
+ constructor(issues: ValidationIssue[], opts?: { cause?: unknown }) {
102
+ super(`validation failed with ${issues.length} issue${issues.length === 1 ? "" : "s"}`, {
103
+ code: "VALIDATION",
104
+ category: "USER_ERROR",
105
+ cause: opts?.cause,
106
+ })
107
+ this.issues = issues
108
+ }
109
+ }
package/src/index.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  // docs/sdk-surface.md §2–§8
5
5
  // docs/design.md §3–§4
6
6
 
7
+ export * from "./conditions.js"
7
8
  export {
8
9
  FatalError,
9
10
  HookConflictError,
@@ -11,8 +12,7 @@ export {
11
12
  RetryableError,
12
13
  TimeoutError,
13
14
  ValidationError,
14
- } from "@voyantjs/workflows-errors"
15
- export * from "./conditions.js"
15
+ } from "./errors.js"
16
16
  export * from "./trigger.js"
17
17
  export * from "./types.js"
18
18
  export * from "./workflow.js"
@@ -1,4 +1,4 @@
1
- // Internal runtime signal errors. Distinct from user-facing `@voyantjs/workflows-errors`:
1
+ // Internal runtime signal errors. Distinct from user-facing `@voyantjs/workflows/errors`:
2
2
  // these are thrown inside the executor to unwind the workflow body on
3
3
  // waitpoint yield or run cancellation. They must not be caught by user
4
4
  // code (the executor re-throws if it observes one being swallowed).