@cellaflow/sdk 0.7.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/dist/cellaflow/v1/common_pb.d.ts +119 -0
- package/dist/cellaflow/v1/common_pb.d.ts.map +1 -0
- package/dist/cellaflow/v1/common_pb.js +166 -0
- package/dist/cellaflow/v1/common_pb.js.map +1 -0
- package/dist/cellaflow/v1/idempotency_pb.d.ts +378 -0
- package/dist/cellaflow/v1/idempotency_pb.d.ts.map +1 -0
- package/dist/cellaflow/v1/idempotency_pb.js +513 -0
- package/dist/cellaflow/v1/idempotency_pb.js.map +1 -0
- package/dist/cellaflow/v1/internal_pb.d.ts +201 -0
- package/dist/cellaflow/v1/internal_pb.d.ts.map +1 -0
- package/dist/cellaflow/v1/internal_pb.js +254 -0
- package/dist/cellaflow/v1/internal_pb.js.map +1 -0
- package/dist/cellaflow/v1/service_connect.d.ts +84 -0
- package/dist/cellaflow/v1/service_connect.d.ts.map +1 -0
- package/dist/cellaflow/v1/service_connect.js +88 -0
- package/dist/cellaflow/v1/service_connect.js.map +1 -0
- package/dist/cellaflow/v1/service_pb.d.ts +172 -0
- package/dist/cellaflow/v1/service_pb.d.ts.map +1 -0
- package/dist/cellaflow/v1/service_pb.js +266 -0
- package/dist/cellaflow/v1/service_pb.js.map +1 -0
- package/dist/client.d.ts +88 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +187 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/serialization.d.ts +18 -0
- package/dist/serialization.d.ts.map +1 -0
- package/dist/serialization.js +41 -0
- package/dist/serialization.js.map +1 -0
- package/package.json +59 -0
- package/src/cellaflow/v1/common_pb.ts +195 -0
- package/src/cellaflow/v1/idempotency_pb.ts +591 -0
- package/src/cellaflow/v1/internal_pb.ts +308 -0
- package/src/cellaflow/v1/service_connect.ts +90 -0
- package/src/cellaflow/v1/service_pb.ts +323 -0
- package/src/client.ts +277 -0
- package/src/index.ts +7 -0
- package/src/serialization.ts +53 -0
package/dist/client.js
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { createPromiseClient, } from "@connectrpc/connect";
|
|
2
|
+
import { createGrpcTransport } from "@connectrpc/connect-node";
|
|
3
|
+
import { WorkflowEngineService } from "./cellaflow/v1/service_connect.js";
|
|
4
|
+
import { serialize, deserialize } from "./serialization.js";
|
|
5
|
+
export class CellaflowClient {
|
|
6
|
+
/**
|
|
7
|
+
* gRPC Client for the Cellaflow Engine (Connect-ES transport).
|
|
8
|
+
* Handles communication with the engine and strictly uses MessagePack
|
|
9
|
+
* for state payloads.
|
|
10
|
+
*/
|
|
11
|
+
client;
|
|
12
|
+
constructor(options = {}) {
|
|
13
|
+
const { target = "localhost:50051", secure = false } = options;
|
|
14
|
+
// Use http/https based on the secure flag
|
|
15
|
+
const baseUrl = secure ? `https://${target}` : `http://${target}`;
|
|
16
|
+
const transport = createGrpcTransport({
|
|
17
|
+
baseUrl,
|
|
18
|
+
httpVersion: "2",
|
|
19
|
+
});
|
|
20
|
+
this.client = createPromiseClient(WorkflowEngineService, transport);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Starts a new workflow execution session.
|
|
24
|
+
*
|
|
25
|
+
* @param workflowId - The workflow definition ID.
|
|
26
|
+
* @param version - The workflow version string.
|
|
27
|
+
* @param sessionId - Optional client-proposed session ID. When provided, the
|
|
28
|
+
* engine performs a transactional check-and-insert to prevent concurrent
|
|
29
|
+
* race conditions. Omit to let the engine assign one.
|
|
30
|
+
*/
|
|
31
|
+
async startSession(workflowId, version, sessionId) {
|
|
32
|
+
const req = { workflowId, version };
|
|
33
|
+
// Only set sessionId when truthy — matches Python's `if session_id:` guard.
|
|
34
|
+
// Sending an empty string may trigger the engine's custom-ID validation path.
|
|
35
|
+
if (sessionId) {
|
|
36
|
+
req.sessionId = sessionId;
|
|
37
|
+
}
|
|
38
|
+
return await this.client.startSession(req);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Commits a completed step result to the session graph.
|
|
42
|
+
*
|
|
43
|
+
* @param sessionId - The session to commit to.
|
|
44
|
+
* @param sequence - The step sequence number (1-based).
|
|
45
|
+
* @param name - Human-readable step name.
|
|
46
|
+
* @param status - The step outcome status.
|
|
47
|
+
* @param outputPayload - Arbitrary step output. Serialized as MessagePack.
|
|
48
|
+
* @param idempotencyKey - Optional idempotency lease key.
|
|
49
|
+
* @param idempotencyFencingToken - Required when `idempotencyKey` is set.
|
|
50
|
+
*/
|
|
51
|
+
async commitStep(sessionId, sequence, name, status, outputPayload, idempotencyKey, idempotencyFencingToken) {
|
|
52
|
+
// Strictly serialize object to MessagePack
|
|
53
|
+
const serializedState = serialize(outputPayload);
|
|
54
|
+
const req = {
|
|
55
|
+
sessionId,
|
|
56
|
+
stepResult: {
|
|
57
|
+
sequence: BigInt(sequence),
|
|
58
|
+
name,
|
|
59
|
+
status,
|
|
60
|
+
outputPayload: Buffer.from(serializedState),
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
if (idempotencyKey !== undefined) {
|
|
64
|
+
req.idempotencyKey = idempotencyKey;
|
|
65
|
+
if (idempotencyFencingToken === undefined) {
|
|
66
|
+
throw new Error("idempotencyFencingToken required if idempotencyKey is set");
|
|
67
|
+
}
|
|
68
|
+
req.idempotencyFencingToken = BigInt(idempotencyFencingToken);
|
|
69
|
+
}
|
|
70
|
+
return await this.client.commitStep(req);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Returns a paginated list of committed step results for a session.
|
|
74
|
+
*
|
|
75
|
+
* @returns A tuple of (step results, next_cursor). `next_cursor` is
|
|
76
|
+
* `undefined` when there are no more pages. Each step result's
|
|
77
|
+
* `outputPayload` is fully deserialized from MessagePack.
|
|
78
|
+
*/
|
|
79
|
+
async getGraph(sessionId, limit, cursor) {
|
|
80
|
+
const req = { sessionId };
|
|
81
|
+
if (limit !== undefined) {
|
|
82
|
+
req.limit = limit;
|
|
83
|
+
}
|
|
84
|
+
if (cursor !== undefined) {
|
|
85
|
+
req.cursor = cursor;
|
|
86
|
+
}
|
|
87
|
+
const resp = await this.client.getGraph(req);
|
|
88
|
+
const results = resp.steps.map((step) => ({
|
|
89
|
+
sequence: step.sequence,
|
|
90
|
+
name: step.name,
|
|
91
|
+
status: step.status,
|
|
92
|
+
// Guard against empty payload (default Uint8Array(0)) to prevent
|
|
93
|
+
// msgpack from throwing on an empty buffer.
|
|
94
|
+
outputPayload: step.outputPayload.length > 0 ? deserialize(step.outputPayload) : {},
|
|
95
|
+
idempotencyKey: step.idempotencyKey,
|
|
96
|
+
}));
|
|
97
|
+
const nextCursor = resp.nextCursor ? resp.nextCursor : undefined;
|
|
98
|
+
return [results, nextCursor];
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Arbitrates the idempotency lease for `idempotencyKey`.
|
|
102
|
+
*
|
|
103
|
+
* Supplying `sessionId` also asks the engine for the session's committed
|
|
104
|
+
* position, returned as `currentSequence` on every status. The idempotency
|
|
105
|
+
* key is opaque to the engine, so the session cannot be inferred from it —
|
|
106
|
+
* without this the engine has nothing to answer from.
|
|
107
|
+
*
|
|
108
|
+
* Supplying `sequence` — the position this caller intends to write to —
|
|
109
|
+
* additionally lets the engine refuse a lease that would authorise a side
|
|
110
|
+
* effect at an already-committed position, instead of rejecting the commit
|
|
111
|
+
* afterwards once the side effect has happened. The engine raises
|
|
112
|
+
* `FAILED_PRECONDITION` when refused. Both fields are optional on the wire;
|
|
113
|
+
* omitting `sequence` keeps the position unguarded.
|
|
114
|
+
*/
|
|
115
|
+
async checkIdempotencyCache(agentId, idempotencyKey, waitTimeoutMs, leaseTtlMs, sessionId, sequence) {
|
|
116
|
+
const req = { agentId, idempotencyKey };
|
|
117
|
+
// These proto fields are uint64 → bigint; convert from the JS number API.
|
|
118
|
+
if (waitTimeoutMs !== undefined) {
|
|
119
|
+
req.waitTimeoutMs = BigInt(waitTimeoutMs);
|
|
120
|
+
}
|
|
121
|
+
if (leaseTtlMs !== undefined) {
|
|
122
|
+
req.leaseTtlMs = BigInt(leaseTtlMs);
|
|
123
|
+
}
|
|
124
|
+
if (sessionId !== undefined) {
|
|
125
|
+
req.sessionId = sessionId;
|
|
126
|
+
}
|
|
127
|
+
if (sequence !== undefined) {
|
|
128
|
+
req.sequence = BigInt(sequence);
|
|
129
|
+
}
|
|
130
|
+
return await this.client.checkIdempotencyCache(req);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Renews a held idempotency lease.
|
|
134
|
+
*
|
|
135
|
+
* @param timeoutSecs - Bounds the RPC in **seconds**. Heartbeat callers
|
|
136
|
+
* MUST supply a positive value: without a deadline a black-holed
|
|
137
|
+
* connection parks the calling thread indefinitely, and the shutdown
|
|
138
|
+
* path that joins that thread parks with it.
|
|
139
|
+
*/
|
|
140
|
+
async renewLease(agentId, idempotencyKey, fencingToken, extendMs, timeoutSecs) {
|
|
141
|
+
const req = {
|
|
142
|
+
agentId,
|
|
143
|
+
idempotencyKey,
|
|
144
|
+
fencingToken: BigInt(fencingToken),
|
|
145
|
+
extendMs: BigInt(extendMs),
|
|
146
|
+
};
|
|
147
|
+
return await this.client.renewLease(req, {
|
|
148
|
+
// Guard against timeout=0 which would cause an instant timeout.
|
|
149
|
+
timeoutMs: timeoutSecs !== undefined && timeoutSecs > 0
|
|
150
|
+
? timeoutSecs * 1000
|
|
151
|
+
: undefined,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Releases a held idempotency lease.
|
|
156
|
+
*
|
|
157
|
+
* @param timeoutSecs - Bounds the RPC in **seconds**.
|
|
158
|
+
*/
|
|
159
|
+
async releaseLease(agentId, idempotencyKey, fencingToken, reason, timeoutSecs) {
|
|
160
|
+
const req = {
|
|
161
|
+
agentId,
|
|
162
|
+
idempotencyKey,
|
|
163
|
+
fencingToken: BigInt(fencingToken),
|
|
164
|
+
};
|
|
165
|
+
if (reason !== undefined) {
|
|
166
|
+
req.reason = reason;
|
|
167
|
+
}
|
|
168
|
+
return await this.client.releaseLease(req, {
|
|
169
|
+
timeoutMs: timeoutSecs !== undefined && timeoutSecs > 0
|
|
170
|
+
? timeoutSecs * 1000
|
|
171
|
+
: undefined,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Provided for API compatibility with the Python client.
|
|
176
|
+
*
|
|
177
|
+
* Connect-ES v1 with `createGrpcTransport` does not expose an explicit
|
|
178
|
+
* close/shutdown method — HTTP/2 sessions are managed by Node.js and are
|
|
179
|
+
* cleaned up on process exit or when the client is garbage-collected.
|
|
180
|
+
* Long-lived server processes with many short-lived clients should let the
|
|
181
|
+
* garbage collector handle cleanup.
|
|
182
|
+
*/
|
|
183
|
+
close() {
|
|
184
|
+
// No-op: Connect-ES v1 does not provide a transport.close() API.
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kCAAkC,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from "./client.js";
|
|
2
|
+
export * from "./serialization.js";
|
|
3
|
+
export * from "./cellaflow/v1/common_pb.js";
|
|
4
|
+
export * from "./cellaflow/v1/idempotency_pb.js";
|
|
5
|
+
// Note: internal_pb is intentionally NOT re-exported here. It contains
|
|
6
|
+
// engine-internal types (CacheRecord, LeaseRecord, etc.) that are not part
|
|
7
|
+
// of the public SDK surface.
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kCAAkC,CAAC;AACjD,uEAAuE;AACvE,2EAA2E;AAC3E,6BAA6B"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serializes a JavaScript object to a MessagePack byte array.
|
|
3
|
+
* This ensures we never use JSON for state payloads, mitigating RCE risks.
|
|
4
|
+
*
|
|
5
|
+
* @throws {TypeError} If `data` is not a plain, non-null object.
|
|
6
|
+
*/
|
|
7
|
+
export declare function serialize(data: Record<string, any>): Uint8Array;
|
|
8
|
+
/**
|
|
9
|
+
* Deserializes a MessagePack byte array back into a JavaScript object.
|
|
10
|
+
*
|
|
11
|
+
* Uses `ArrayBuffer.isView()` instead of `instanceof Uint8Array` to work
|
|
12
|
+
* correctly across JS realms (worker threads, vm contexts, etc.).
|
|
13
|
+
*
|
|
14
|
+
* @throws {TypeError} If `data` is not a Uint8Array / ArrayBufferView.
|
|
15
|
+
* @throws {TypeError} If the deserialized value is not a plain object.
|
|
16
|
+
*/
|
|
17
|
+
export declare function deserialize(data: Uint8Array): Record<string, any>;
|
|
18
|
+
//# sourceMappingURL=serialization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../src/serialization.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,UAAU,CAY/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAqBjE"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { encode, decode } from "@msgpack/msgpack";
|
|
2
|
+
/**
|
|
3
|
+
* Serializes a JavaScript object to a MessagePack byte array.
|
|
4
|
+
* This ensures we never use JSON for state payloads, mitigating RCE risks.
|
|
5
|
+
*
|
|
6
|
+
* @throws {TypeError} If `data` is not a plain, non-null object.
|
|
7
|
+
*/
|
|
8
|
+
export function serialize(data) {
|
|
9
|
+
// Explicit null check first — `typeof null === "object"` would otherwise
|
|
10
|
+
// produce a misleading error message reporting "got object" instead of "got null".
|
|
11
|
+
if (data === null) {
|
|
12
|
+
throw new TypeError("Expected an object for serialization, got null");
|
|
13
|
+
}
|
|
14
|
+
if (typeof data !== "object" || Array.isArray(data)) {
|
|
15
|
+
throw new TypeError(`Expected an object for serialization, got ${Array.isArray(data) ? "array" : typeof data}`);
|
|
16
|
+
}
|
|
17
|
+
return encode(data);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Deserializes a MessagePack byte array back into a JavaScript object.
|
|
21
|
+
*
|
|
22
|
+
* Uses `ArrayBuffer.isView()` instead of `instanceof Uint8Array` to work
|
|
23
|
+
* correctly across JS realms (worker threads, vm contexts, etc.).
|
|
24
|
+
*
|
|
25
|
+
* @throws {TypeError} If `data` is not a Uint8Array / ArrayBufferView.
|
|
26
|
+
* @throws {TypeError} If the deserialized value is not a plain object.
|
|
27
|
+
*/
|
|
28
|
+
export function deserialize(data) {
|
|
29
|
+
// ArrayBuffer.isView is cross-realm safe; instanceof Uint8Array is not.
|
|
30
|
+
if (!ArrayBuffer.isView(data)) {
|
|
31
|
+
throw new TypeError(`Expected Uint8Array for deserialization, got ${data === null ? "null" : typeof data}`);
|
|
32
|
+
}
|
|
33
|
+
const unpacked = decode(data);
|
|
34
|
+
if (typeof unpacked !== "object" ||
|
|
35
|
+
unpacked === null ||
|
|
36
|
+
Array.isArray(unpacked)) {
|
|
37
|
+
throw new TypeError(`Deserialized data is not an object, got ${unpacked === null ? "null" : typeof unpacked}`);
|
|
38
|
+
}
|
|
39
|
+
return unpacked;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=serialization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialization.js","sourceRoot":"","sources":["../src/serialization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAElD;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,IAAyB;IACjD,yEAAyE;IACzE,mFAAmF;IACnF,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,MAAM,IAAI,SAAS,CAAC,gDAAgD,CAAC,CAAC;IACxE,CAAC;IACD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,SAAS,CACjB,6CAA6C,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAC3F,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,IAAgB;IAC1C,wEAAwE;IACxE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,SAAS,CACjB,gDAAgD,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CACvF,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAE9B,IACE,OAAO,QAAQ,KAAK,QAAQ;QAC5B,QAAQ,KAAK,IAAI;QACjB,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EACvB,CAAC;QACD,MAAM,IAAI,SAAS,CACjB,2CAA2C,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,QAAQ,EAAE,CAC1F,CAAC;IACJ,CAAC;IAED,OAAO,QAA+B,CAAC;AACzC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cellaflow/sdk",
|
|
3
|
+
"version": "0.7.0",
|
|
4
|
+
"description": "TypeScript/Node.js SDK for the Cellaflow workflow engine",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist/",
|
|
16
|
+
"src/",
|
|
17
|
+
"README.md",
|
|
18
|
+
"CHANGELOG.md"
|
|
19
|
+
],
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=18.0.0"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc",
|
|
25
|
+
"prepublishOnly": "npm run build",
|
|
26
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"cellaflow",
|
|
30
|
+
"workflow",
|
|
31
|
+
"grpc",
|
|
32
|
+
"connect-rpc",
|
|
33
|
+
"sdk"
|
|
34
|
+
],
|
|
35
|
+
"author": "Cellaflow <hello@cellaflow.com>",
|
|
36
|
+
"license": "Apache-2.0",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/cellaflow/cellaflow-sdks.git",
|
|
40
|
+
"directory": "typescript"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/cellaflow/cellaflow-sdks/tree/main/typescript#readme",
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/cellaflow/cellaflow-sdks/issues"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@bufbuild/protobuf": "^1.10.1",
|
|
48
|
+
"@connectrpc/connect": "^1.7.0",
|
|
49
|
+
"@connectrpc/connect-node": "^1.7.0",
|
|
50
|
+
"@msgpack/msgpack": "^3.1.3"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@bufbuild/buf": "^1.73.0",
|
|
54
|
+
"@bufbuild/protoc-gen-es": "^1.10.1",
|
|
55
|
+
"@connectrpc/protoc-gen-connect-es": "^1.7.0",
|
|
56
|
+
"@types/node": "^26.6.2",
|
|
57
|
+
"typescript": "^7.0.2"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
// @generated by protoc-gen-es v1.10.1 with parameter "target=ts,import_extension=.js"
|
|
2
|
+
// @generated from file cellaflow/v1/common.proto (package cellaflow.v1, syntax proto3)
|
|
3
|
+
/* eslint-disable */
|
|
4
|
+
// @ts-nocheck
|
|
5
|
+
|
|
6
|
+
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
|
|
7
|
+
import { Message, proto3 } from "@bufbuild/protobuf";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* StepStatus defines compile-time type-safe execution states for a step.
|
|
11
|
+
*
|
|
12
|
+
* @generated from enum cellaflow.v1.StepStatus
|
|
13
|
+
*/
|
|
14
|
+
export enum StepStatus {
|
|
15
|
+
/**
|
|
16
|
+
* @generated from enum value: STEP_STATUS_UNSPECIFIED = 0;
|
|
17
|
+
*/
|
|
18
|
+
UNSPECIFIED = 0,
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @generated from enum value: STEP_STATUS_RUNNING = 1;
|
|
22
|
+
*/
|
|
23
|
+
RUNNING = 1,
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @generated from enum value: STEP_STATUS_SUCCESS = 2;
|
|
27
|
+
*/
|
|
28
|
+
SUCCESS = 2,
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @generated from enum value: STEP_STATUS_FAILED = 3;
|
|
32
|
+
*/
|
|
33
|
+
FAILED = 3,
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @generated from enum value: STEP_STATUS_TIMER_SCHEDULED = 4;
|
|
37
|
+
*/
|
|
38
|
+
TIMER_SCHEDULED = 4,
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @generated from enum value: STEP_STATUS_TIMER_FIRED = 5;
|
|
42
|
+
*/
|
|
43
|
+
TIMER_FIRED = 5,
|
|
44
|
+
}
|
|
45
|
+
// Retrieve enum metadata with: proto3.getEnumType(StepStatus)
|
|
46
|
+
proto3.util.setEnumType(StepStatus, "cellaflow.v1.StepStatus", [
|
|
47
|
+
{ no: 0, name: "STEP_STATUS_UNSPECIFIED" },
|
|
48
|
+
{ no: 1, name: "STEP_STATUS_RUNNING" },
|
|
49
|
+
{ no: 2, name: "STEP_STATUS_SUCCESS" },
|
|
50
|
+
{ no: 3, name: "STEP_STATUS_FAILED" },
|
|
51
|
+
{ no: 4, name: "STEP_STATUS_TIMER_SCHEDULED" },
|
|
52
|
+
{ no: 5, name: "STEP_STATUS_TIMER_FIRED" },
|
|
53
|
+
]);
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* StepResult represents the outcome of a single step in a workflow execution session.
|
|
57
|
+
*
|
|
58
|
+
* @generated from message cellaflow.v1.StepResult
|
|
59
|
+
*/
|
|
60
|
+
export class StepResult extends Message<StepResult> {
|
|
61
|
+
/**
|
|
62
|
+
* Optional to distinguish between explicit sequence 0 and unset/omitted values.
|
|
63
|
+
* Validation: Must be greater than 0 during normal execution.
|
|
64
|
+
*
|
|
65
|
+
* @generated from field: optional uint64 sequence = 1;
|
|
66
|
+
*/
|
|
67
|
+
sequence?: bigint;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @generated from field: string name = 2;
|
|
71
|
+
*/
|
|
72
|
+
name = "";
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Safe enum-typed status to prevent raw string errors (e.g. typos).
|
|
76
|
+
*
|
|
77
|
+
* @generated from field: cellaflow.v1.StepStatus status = 3;
|
|
78
|
+
*/
|
|
79
|
+
status = StepStatus.UNSPECIFIED;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Output payload generated by this execution step.
|
|
83
|
+
* Validation: Size must not exceed 4MB (4,194,304 bytes).
|
|
84
|
+
*
|
|
85
|
+
* @generated from field: bytes output_payload = 4;
|
|
86
|
+
*/
|
|
87
|
+
outputPayload = new Uint8Array(0);
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Unique idempotency key to prevent duplicate tool execution.
|
|
91
|
+
* Validation: If specified, must not be empty.
|
|
92
|
+
*
|
|
93
|
+
* @generated from field: optional string idempotency_key = 5;
|
|
94
|
+
*/
|
|
95
|
+
idempotencyKey?: string;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Deadline for the sleep operation, represented as a Unix timestamp in milliseconds.
|
|
99
|
+
* Used when status is STEP_STATUS_TIMER_SCHEDULED.
|
|
100
|
+
*
|
|
101
|
+
* @generated from field: optional uint64 deadline_ms = 6;
|
|
102
|
+
*/
|
|
103
|
+
deadlineMs?: bigint;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* The sequence number of the originating TimerScheduled event.
|
|
107
|
+
* Used when status is STEP_STATUS_TIMER_FIRED to explicitly pair events.
|
|
108
|
+
*
|
|
109
|
+
* @generated from field: optional uint64 source_sequence = 7;
|
|
110
|
+
*/
|
|
111
|
+
sourceSequence?: bigint;
|
|
112
|
+
|
|
113
|
+
constructor(data?: PartialMessage<StepResult>) {
|
|
114
|
+
super();
|
|
115
|
+
proto3.util.initPartial(data, this);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
static readonly runtime: typeof proto3 = proto3;
|
|
119
|
+
static readonly typeName = "cellaflow.v1.StepResult";
|
|
120
|
+
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
|
121
|
+
{ no: 1, name: "sequence", kind: "scalar", T: 4 /* ScalarType.UINT64 */, opt: true },
|
|
122
|
+
{ no: 2, name: "name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
|
123
|
+
{ no: 3, name: "status", kind: "enum", T: proto3.getEnumType(StepStatus) },
|
|
124
|
+
{ no: 4, name: "output_payload", kind: "scalar", T: 12 /* ScalarType.BYTES */ },
|
|
125
|
+
{ no: 5, name: "idempotency_key", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true },
|
|
126
|
+
{ no: 6, name: "deadline_ms", kind: "scalar", T: 4 /* ScalarType.UINT64 */, opt: true },
|
|
127
|
+
{ no: 7, name: "source_sequence", kind: "scalar", T: 4 /* ScalarType.UINT64 */, opt: true },
|
|
128
|
+
]);
|
|
129
|
+
|
|
130
|
+
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): StepResult {
|
|
131
|
+
return new StepResult().fromBinary(bytes, options);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): StepResult {
|
|
135
|
+
return new StepResult().fromJson(jsonValue, options);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): StepResult {
|
|
139
|
+
return new StepResult().fromJsonString(jsonString, options);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
static equals(a: StepResult | PlainMessage<StepResult> | undefined, b: StepResult | PlainMessage<StepResult> | undefined): boolean {
|
|
143
|
+
return proto3.util.equals(StepResult, a, b);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* @generated from message cellaflow.v1.WorkflowDefinition
|
|
149
|
+
*/
|
|
150
|
+
export class WorkflowDefinition extends Message<WorkflowDefinition> {
|
|
151
|
+
/**
|
|
152
|
+
* @generated from field: string id = 1;
|
|
153
|
+
*/
|
|
154
|
+
id = "";
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* @generated from field: string version = 2;
|
|
158
|
+
*/
|
|
159
|
+
version = "";
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* @generated from field: string description = 3;
|
|
163
|
+
*/
|
|
164
|
+
description = "";
|
|
165
|
+
|
|
166
|
+
constructor(data?: PartialMessage<WorkflowDefinition>) {
|
|
167
|
+
super();
|
|
168
|
+
proto3.util.initPartial(data, this);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
static readonly runtime: typeof proto3 = proto3;
|
|
172
|
+
static readonly typeName = "cellaflow.v1.WorkflowDefinition";
|
|
173
|
+
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
|
174
|
+
{ no: 1, name: "id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
|
175
|
+
{ no: 2, name: "version", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
|
176
|
+
{ no: 3, name: "description", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
|
177
|
+
]);
|
|
178
|
+
|
|
179
|
+
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): WorkflowDefinition {
|
|
180
|
+
return new WorkflowDefinition().fromBinary(bytes, options);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): WorkflowDefinition {
|
|
184
|
+
return new WorkflowDefinition().fromJson(jsonValue, options);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): WorkflowDefinition {
|
|
188
|
+
return new WorkflowDefinition().fromJsonString(jsonString, options);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
static equals(a: WorkflowDefinition | PlainMessage<WorkflowDefinition> | undefined, b: WorkflowDefinition | PlainMessage<WorkflowDefinition> | undefined): boolean {
|
|
192
|
+
return proto3.util.equals(WorkflowDefinition, a, b);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|