@renderinc/sdk 0.3.0 → 0.4.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 +159 -42
- package/dist/experimental/experimental.d.ts +2 -2
- package/dist/experimental/experimental.d.ts.map +1 -1
- package/dist/experimental/experimental.js +4 -4
- package/dist/experimental/object/client.d.ts +10 -6
- package/dist/experimental/object/client.d.ts.map +1 -1
- package/dist/experimental/object/client.js +33 -9
- package/dist/experimental/object/e2e-helpers.d.ts +3 -0
- package/dist/experimental/object/e2e-helpers.d.ts.map +1 -0
- package/dist/experimental/object/e2e-helpers.js +70 -0
- package/dist/experimental/object/types.d.ts +1 -0
- package/dist/experimental/object/types.d.ts.map +1 -1
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +3 -1
- package/dist/workflows/client/client.d.ts +7 -3
- package/dist/workflows/client/client.d.ts.map +1 -1
- package/dist/workflows/client/client.js +96 -15
- package/dist/workflows/client/index.d.ts +2 -0
- package/dist/workflows/client/index.d.ts.map +1 -1
- package/dist/workflows/client/index.js +5 -1
- package/dist/workflows/client/sse.d.ts +0 -7
- package/dist/workflows/client/sse.d.ts.map +1 -1
- package/dist/workflows/client/sse.js +1 -71
- package/dist/workflows/client/task-run-promise.d.ts +12 -0
- package/dist/workflows/client/task-run-promise.d.ts.map +1 -0
- package/dist/workflows/client/task-run-promise.js +22 -0
- package/dist/workflows/client/task-run-result.d.ts +10 -0
- package/dist/workflows/client/task-run-result.d.ts.map +1 -0
- package/dist/workflows/client/task-run-result.js +18 -0
- package/dist/workflows/client/types.d.ts +2 -0
- package/dist/workflows/client/types.d.ts.map +1 -1
- package/dist/workflows/uds.d.ts +1 -0
- package/dist/workflows/uds.d.ts.map +1 -1
- package/dist/workflows/uds.js +27 -0
- package/dist/workflows/workflows.d.ts +19 -0
- package/dist/workflows/workflows.d.ts.map +1 -0
- package/dist/workflows/workflows.js +51 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -30,6 +30,12 @@ Or with pnpm:
|
|
|
30
30
|
pnpm add @renderinc/sdk
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
+
Or with Bun:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
bun add @renderinc/sdk
|
|
37
|
+
```
|
|
38
|
+
|
|
33
39
|
## Quick Start
|
|
34
40
|
|
|
35
41
|
### REST API Client
|
|
@@ -47,11 +53,13 @@ const result = await render.workflows.runTask('my-workflow/my-task', [42, 'hello
|
|
|
47
53
|
console.log('Status:', result.status);
|
|
48
54
|
console.log('Results:', result.results);
|
|
49
55
|
|
|
56
|
+
// Or start a task and decide when to await the result
|
|
57
|
+
const run = await render.workflows.startTask('my-workflow/my-task', [42, 'hello']);
|
|
58
|
+
console.log('Task run ID:', run.taskRunId);
|
|
59
|
+
const details = await run.get();
|
|
60
|
+
|
|
50
61
|
// List recent task runs
|
|
51
62
|
const taskRuns = await render.workflows.listTaskRuns({ limit: 10 });
|
|
52
|
-
|
|
53
|
-
// Get specific task run
|
|
54
|
-
const details = await render.workflows.getTaskRun(result.id);
|
|
55
63
|
```
|
|
56
64
|
|
|
57
65
|
Alternatively, you can create a workflows client directly:
|
|
@@ -125,9 +133,12 @@ Creates a new Render SDK instance with access to all Render products.
|
|
|
125
133
|
- `baseUrl?: string` - Base URL (defaults to `https://api.render.com`)
|
|
126
134
|
- `useLocalDev?: boolean` - Use local development mode
|
|
127
135
|
- `localDevUrl?: string` - Local development URL
|
|
136
|
+
- `ownerId?: string` - Default owner ID for object storage (falls back to `RENDER_WORKSPACE_ID` env var)
|
|
137
|
+
- `region?: string` - Default region for object storage (falls back to `RENDER_REGION` env var)
|
|
128
138
|
|
|
129
139
|
**Properties:**
|
|
130
140
|
- `workflows` - WorkflowsClient instance for managing workflow tasks
|
|
141
|
+
- `experimental` - ExperimentalClient instance for object storage and other experimental APIs
|
|
131
142
|
|
|
132
143
|
**Example:**
|
|
133
144
|
```typescript
|
|
@@ -175,6 +186,56 @@ const result = await render.workflows.runTask('my-workflow/square', [5]);
|
|
|
175
186
|
console.log('Results:', result.results);
|
|
176
187
|
```
|
|
177
188
|
|
|
189
|
+
#### `render.workflows.startTask(taskIdentifier, inputData, signal?)`
|
|
190
|
+
|
|
191
|
+
Starts a task run and returns a `TaskRunResult`. Results are not streamed until you call `.get()` on the returned result. Use this when you need the task run ID, want to defer awaiting, or want fire-and-forget.
|
|
192
|
+
|
|
193
|
+
**Parameters:**
|
|
194
|
+
- `taskIdentifier: string` - Task identifier in format "workflow-slug/task-name"
|
|
195
|
+
- `inputData: any[]` - Input data as array of parameters
|
|
196
|
+
- `signal?: AbortSignal` - Optional abort signal for cancellation
|
|
197
|
+
|
|
198
|
+
**Returns:** `Promise<TaskRunResult>`
|
|
199
|
+
|
|
200
|
+
**Example:**
|
|
201
|
+
```typescript
|
|
202
|
+
const render = new Render();
|
|
203
|
+
|
|
204
|
+
// Start a task and grab its ID
|
|
205
|
+
const run = await render.workflows.startTask('my-workflow/square', [5]);
|
|
206
|
+
console.log('Task run ID:', run.taskRunId);
|
|
207
|
+
|
|
208
|
+
// Await the result when you're ready
|
|
209
|
+
const result = await run.get();
|
|
210
|
+
console.log('Results:', result.results);
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
#### `render.workflows.taskRunEvents(taskRunIds, signal?)`
|
|
214
|
+
|
|
215
|
+
Streams task run events as an async iterable. Yields a `TaskRunDetails` for each terminal event (completed or failed) received on the stream.
|
|
216
|
+
|
|
217
|
+
**Parameters:**
|
|
218
|
+
- `taskRunIds: string[]` - One or more task run IDs to subscribe to
|
|
219
|
+
- `signal?: AbortSignal` - Optional abort signal for cancellation
|
|
220
|
+
|
|
221
|
+
**Returns:** `AsyncGenerator<TaskRunDetails>`
|
|
222
|
+
|
|
223
|
+
**Example:**
|
|
224
|
+
```typescript
|
|
225
|
+
const render = new Render();
|
|
226
|
+
|
|
227
|
+
const run1 = await render.workflows.startTask('my-workflow/square', [3]);
|
|
228
|
+
const run2 = await render.workflows.startTask('my-workflow/square', [6]);
|
|
229
|
+
|
|
230
|
+
// The stream stays open until you break or abort.
|
|
231
|
+
const pending = new Set([run1.taskRunId, run2.taskRunId]);
|
|
232
|
+
for await (const event of render.workflows.taskRunEvents([...pending])) {
|
|
233
|
+
console.log('Event:', event.status, event.id, event.results);
|
|
234
|
+
pending.delete(event.id);
|
|
235
|
+
if (pending.size === 0) break;
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
178
239
|
#### `render.workflows.getTaskRun(taskRunId)`
|
|
179
240
|
|
|
180
241
|
Gets task run details by ID.
|
|
@@ -190,6 +251,22 @@ const render = new Render();
|
|
|
190
251
|
const details = await render.workflows.getTaskRun('task-run-id');
|
|
191
252
|
```
|
|
192
253
|
|
|
254
|
+
#### `render.workflows.cancelTaskRun(taskRunId)`
|
|
255
|
+
|
|
256
|
+
Cancels a running task.
|
|
257
|
+
|
|
258
|
+
**Parameters:**
|
|
259
|
+
- `taskRunId: string` - Task run ID to cancel
|
|
260
|
+
|
|
261
|
+
**Returns:** `Promise<void>`
|
|
262
|
+
|
|
263
|
+
**Example:**
|
|
264
|
+
```typescript
|
|
265
|
+
const render = new Render();
|
|
266
|
+
const run = await render.workflows.startTask('my-workflow/square', [5]);
|
|
267
|
+
await render.workflows.cancelTaskRun(run.taskRunId);
|
|
268
|
+
```
|
|
269
|
+
|
|
193
270
|
#### `render.workflows.listTaskRuns(params)`
|
|
194
271
|
|
|
195
272
|
Lists task runs with optional filters.
|
|
@@ -300,20 +377,36 @@ enum TaskRunStatus {
|
|
|
300
377
|
```typescript
|
|
301
378
|
interface TaskRun {
|
|
302
379
|
id: string;
|
|
380
|
+
taskId: string;
|
|
303
381
|
status: TaskRunStatus;
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
382
|
+
startedAt?: string;
|
|
383
|
+
completedAt?: string;
|
|
384
|
+
parentTaskRunId: string;
|
|
385
|
+
rootTaskRunId: string;
|
|
386
|
+
retries: number;
|
|
307
387
|
}
|
|
308
388
|
```
|
|
309
389
|
|
|
310
390
|
#### `TaskRunDetails`
|
|
311
391
|
|
|
312
392
|
```typescript
|
|
313
|
-
interface TaskRunDetails
|
|
314
|
-
|
|
315
|
-
|
|
393
|
+
interface TaskRunDetails {
|
|
394
|
+
id: string;
|
|
395
|
+
taskId: string;
|
|
396
|
+
status: TaskRunStatus;
|
|
397
|
+
results?: any;
|
|
316
398
|
error?: string;
|
|
399
|
+
startedAt?: string;
|
|
400
|
+
completedAt?: string;
|
|
401
|
+
}
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
#### `TaskRunResult`
|
|
405
|
+
|
|
406
|
+
```typescript
|
|
407
|
+
class TaskRunResult {
|
|
408
|
+
readonly taskRunId: string;
|
|
409
|
+
get(): Promise<TaskRunDetails>;
|
|
317
410
|
}
|
|
318
411
|
```
|
|
319
412
|
|
|
@@ -340,6 +433,7 @@ The SDK provides several error classes:
|
|
|
340
433
|
import { Render } from '@renderinc/sdk';
|
|
341
434
|
import {
|
|
342
435
|
RenderError,
|
|
436
|
+
TaskRunError,
|
|
343
437
|
ClientError,
|
|
344
438
|
ServerError,
|
|
345
439
|
AbortError,
|
|
@@ -350,7 +444,9 @@ const render = new Render();
|
|
|
350
444
|
try {
|
|
351
445
|
const result = await render.workflows.runTask('my-workflow/task', [42]);
|
|
352
446
|
} catch (error) {
|
|
353
|
-
if (error instanceof
|
|
447
|
+
if (error instanceof TaskRunError) {
|
|
448
|
+
console.error('Task failed:', error.taskRunId, error.message);
|
|
449
|
+
} else if (error instanceof ClientError) {
|
|
354
450
|
console.error('Client error:', error.statusCode, error.cause);
|
|
355
451
|
} else if (error instanceof ServerError) {
|
|
356
452
|
console.error('Server error:', error.statusCode, error.cause);
|
|
@@ -365,11 +461,36 @@ try {
|
|
|
365
461
|
## Environment Variables
|
|
366
462
|
|
|
367
463
|
- `RENDER_API_KEY` - Your Render API key (required)
|
|
464
|
+
- `RENDER_WORKSPACE_ID` - Default owner ID for object storage (workspace team ID, e.g. `tea-xxxxx`)
|
|
465
|
+
- `RENDER_REGION` - Default region for object storage (e.g. `oregon`, `frankfurt`)
|
|
368
466
|
- `RENDER_USE_LOCAL_DEV` - Enable local development mode (`true`/`false`)
|
|
369
467
|
- `RENDER_LOCAL_DEV_URL` - Local development URL (default: `http://localhost:8120`)
|
|
370
468
|
- `RENDER_SDK_MODE` - Task execution mode (`run` or `register`)
|
|
371
469
|
- `RENDER_SDK_SOCKET_PATH` - Unix socket path for task communication
|
|
372
470
|
|
|
471
|
+
### Object Storage
|
|
472
|
+
|
|
473
|
+
When running on Render, `RENDER_WORKSPACE_ID` and `RENDER_REGION` are set automatically. You can also pass them as constructor options:
|
|
474
|
+
|
|
475
|
+
```typescript
|
|
476
|
+
import { Render } from '@renderinc/sdk';
|
|
477
|
+
|
|
478
|
+
const render = new Render(); // Uses env vars for auth + object storage defaults
|
|
479
|
+
|
|
480
|
+
// Upload (no need to pass ownerId/region when env vars are set)
|
|
481
|
+
await render.experimental.storage.objects.put({
|
|
482
|
+
key: 'path/to/file.png',
|
|
483
|
+
data: Buffer.from('binary content'),
|
|
484
|
+
contentType: 'image/png',
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
// Download
|
|
488
|
+
const obj = await render.experimental.storage.objects.get({ key: 'path/to/file.png' });
|
|
489
|
+
|
|
490
|
+
// List
|
|
491
|
+
const response = await render.experimental.storage.objects.list();
|
|
492
|
+
```
|
|
493
|
+
|
|
373
494
|
## Examples
|
|
374
495
|
|
|
375
496
|
### Example 1: Running a Task
|
|
@@ -379,18 +500,14 @@ import { Render } from '@renderinc/sdk';
|
|
|
379
500
|
|
|
380
501
|
const render = new Render();
|
|
381
502
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
console.log('Square of 5 is:', result.results[0]); // 25
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
runSquareTask();
|
|
503
|
+
const result = await render.workflows.runTask('my-workflow/square', [5]);
|
|
504
|
+
console.log('Square of 5 is:', result.results[0]); // 25
|
|
388
505
|
```
|
|
389
506
|
|
|
390
507
|
### Example 2: Defining Tasks with Subtasks
|
|
391
508
|
|
|
392
509
|
```typescript
|
|
393
|
-
import { task
|
|
510
|
+
import { task } from '@renderinc/sdk/workflows';
|
|
394
511
|
|
|
395
512
|
const square = task(
|
|
396
513
|
{ name: 'square' },
|
|
@@ -407,8 +524,6 @@ task(
|
|
|
407
524
|
return Math.sqrt(aSquared + bSquared);
|
|
408
525
|
}
|
|
409
526
|
);
|
|
410
|
-
|
|
411
|
-
await startTaskServer();
|
|
412
527
|
```
|
|
413
528
|
|
|
414
529
|
### Example 3: Error Handling in Tasks
|
|
@@ -502,8 +617,7 @@ async function workflowExample() {
|
|
|
502
617
|
console.log(`\nRecent task runs: ${recentRuns.length}`);
|
|
503
618
|
|
|
504
619
|
for (const run of recentRuns) {
|
|
505
|
-
|
|
506
|
-
console.log(`- ${run.taskId}: ${details.status}`);
|
|
620
|
+
console.log(`- ${run.id}: ${run.status} (${run.taskId})`);
|
|
507
621
|
}
|
|
508
622
|
} catch (error) {
|
|
509
623
|
console.error('Error:', error);
|
|
@@ -544,30 +658,33 @@ npm run format
|
|
|
544
658
|
```
|
|
545
659
|
typescript/
|
|
546
660
|
├── src/
|
|
547
|
-
│ ├── render.ts
|
|
548
|
-
│ ├──
|
|
549
|
-
│
|
|
550
|
-
│
|
|
551
|
-
│
|
|
552
|
-
│
|
|
553
|
-
│
|
|
554
|
-
│
|
|
555
|
-
│
|
|
556
|
-
│
|
|
557
|
-
│
|
|
558
|
-
│
|
|
559
|
-
│
|
|
560
|
-
│
|
|
561
|
-
│
|
|
562
|
-
│
|
|
563
|
-
│
|
|
564
|
-
│
|
|
565
|
-
│
|
|
661
|
+
│ ├── render.ts # Main Render SDK class
|
|
662
|
+
│ ├── errors.ts # Error classes
|
|
663
|
+
│ ├── index.ts # Main exports
|
|
664
|
+
│ ├── version.ts # SDK version and user-agent
|
|
665
|
+
│ ├── workflows/ # Workflows functionality
|
|
666
|
+
│ │ ├── task.ts # task() function
|
|
667
|
+
│ │ ├── runner.ts # startTaskServer() and run()
|
|
668
|
+
│ │ ├── executor.ts # TaskExecutor
|
|
669
|
+
│ │ ├── registry.ts # TaskRegistry
|
|
670
|
+
│ │ ├── uds.ts # Unix socket client
|
|
671
|
+
│ │ ├── types.ts # Type definitions
|
|
672
|
+
│ │ ├── client/ # REST API client
|
|
673
|
+
│ │ │ ├── client.ts # WorkflowsClient class
|
|
674
|
+
│ │ │ ├── create-client.ts # createWorkflowsClient() factory
|
|
675
|
+
│ │ │ ├── task-run-result.ts # TaskRunResult class
|
|
676
|
+
│ │ │ ├── sse.ts # SSE event types
|
|
677
|
+
│ │ │ ├── types.ts # Client type definitions
|
|
678
|
+
│ │ │ └── index.ts # Exports
|
|
679
|
+
│ │ └── index.ts # Workflows exports
|
|
680
|
+
│ ├── experimental/ # Experimental features
|
|
681
|
+
│ │ └── object/ # Object storage API
|
|
682
|
+
│ └── utils/ # Shared utilities
|
|
566
683
|
├── examples/
|
|
567
|
-
│ ├── client/
|
|
684
|
+
│ ├── client/ # Client example
|
|
568
685
|
│ │ ├── main.ts
|
|
569
686
|
│ │ └── package.json
|
|
570
|
-
│ └── task/
|
|
687
|
+
│ └── task/ # Task example
|
|
571
688
|
│ ├── main.ts
|
|
572
689
|
│ └── package.json
|
|
573
690
|
├── package.json
|
|
@@ -3,10 +3,10 @@ import type { paths } from "../generated/schema.js";
|
|
|
3
3
|
import { ObjectClient } from "./object/client.js";
|
|
4
4
|
export declare class StorageClient {
|
|
5
5
|
readonly objects: ObjectClient;
|
|
6
|
-
constructor(apiClient: Client<paths
|
|
6
|
+
constructor(apiClient: Client<paths>, defaultOwnerId?: string, defaultRegion?: string);
|
|
7
7
|
}
|
|
8
8
|
export declare class ExperimentalClient {
|
|
9
9
|
readonly storage: StorageClient;
|
|
10
|
-
constructor(apiClient: Client<paths
|
|
10
|
+
constructor(apiClient: Client<paths>, defaultOwnerId?: string, defaultRegion?: string);
|
|
11
11
|
}
|
|
12
12
|
//# sourceMappingURL=experimental.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"experimental.d.ts","sourceRoot":"","sources":["../../src/experimental/experimental.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAgBlD,qBAAa,aAAa;IAExB,SAAgB,OAAO,EAAE,YAAY,CAAC;gBAE1B,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"experimental.d.ts","sourceRoot":"","sources":["../../src/experimental/experimental.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAgBlD,qBAAa,aAAa;IAExB,SAAgB,OAAO,EAAE,YAAY,CAAC;gBAE1B,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM;CAGtF;AAuBD,qBAAa,kBAAkB;IAE7B,SAAgB,OAAO,EAAE,aAAa,CAAC;gBAE3B,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM;CAGtF"}
|
|
@@ -3,14 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ExperimentalClient = exports.StorageClient = void 0;
|
|
4
4
|
const client_js_1 = require("./object/client.js");
|
|
5
5
|
class StorageClient {
|
|
6
|
-
constructor(apiClient) {
|
|
7
|
-
this.objects = new client_js_1.ObjectClient(apiClient);
|
|
6
|
+
constructor(apiClient, defaultOwnerId, defaultRegion) {
|
|
7
|
+
this.objects = new client_js_1.ObjectClient(apiClient, defaultOwnerId, defaultRegion);
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
exports.StorageClient = StorageClient;
|
|
11
11
|
class ExperimentalClient {
|
|
12
|
-
constructor(apiClient) {
|
|
13
|
-
this.storage = new StorageClient(apiClient);
|
|
12
|
+
constructor(apiClient, defaultOwnerId, defaultRegion) {
|
|
13
|
+
this.storage = new StorageClient(apiClient, defaultOwnerId, defaultRegion);
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
exports.ExperimentalClient = ExperimentalClient;
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import type { Client } from "openapi-fetch";
|
|
2
2
|
import type { paths } from "../../generated/schema.js";
|
|
3
|
-
import type { DeleteObjectInput, GetObjectInput, ListObjectsInput, ListObjectsResponse, ObjectData, ObjectScope, PutObjectInput, PutObjectResult, ScopedDeleteObjectInput, ScopedGetObjectInput, ScopedListObjectsInput, ScopedPutObjectInput } from "./types.js";
|
|
3
|
+
import type { DeleteObjectInput, GetObjectInput, ListObjectsInput, ListObjectsResponse, ObjectData, ObjectScope, OptionalScope, PutObjectInput, PutObjectResult, ScopedDeleteObjectInput, ScopedGetObjectInput, ScopedListObjectsInput, ScopedPutObjectInput } from "./types.js";
|
|
4
4
|
export declare class ObjectClient {
|
|
5
5
|
private readonly apiClient;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
private readonly defaultOwnerId?;
|
|
7
|
+
private readonly defaultRegion?;
|
|
8
|
+
constructor(apiClient: Client<paths>, defaultOwnerId?: string, defaultRegion?: string);
|
|
9
|
+
private resolveOwnerId;
|
|
10
|
+
private resolveRegion;
|
|
11
|
+
put(input: OptionalScope<PutObjectInput>): Promise<PutObjectResult>;
|
|
12
|
+
get(input: OptionalScope<GetObjectInput>): Promise<ObjectData>;
|
|
13
|
+
delete(input: OptionalScope<DeleteObjectInput>): Promise<void>;
|
|
14
|
+
list(input: OptionalScope<ListObjectsInput>): Promise<ListObjectsResponse>;
|
|
11
15
|
scoped(scope: ObjectScope): ScopedObjectClient;
|
|
12
16
|
private resolveSize;
|
|
13
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/experimental/object/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,UAAU,EAEV,WAAW,EACX,cAAc,EACd,eAAe,EAEf,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AASpB,qBAAa,YAAY;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/experimental/object/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,UAAU,EAEV,WAAW,EACX,aAAa,EACb,cAAc,EACd,eAAe,EAEf,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AASpB,qBAAa,YAAY;IAKrB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAJ5B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAkB;gBAG9B,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,EACzC,cAAc,CAAC,EAAE,MAAM,EACvB,aAAa,CAAC,EAAE,MAAM;IAMxB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,aAAa;IA4Cf,GAAG,CAAC,KAAK,EAAE,aAAa,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC;IAwFnE,GAAG,CAAC,KAAK,EAAE,aAAa,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;IAkD9D,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAgD9D,IAAI,CAAC,KAAK,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAiDhF,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,kBAAkB;IAU9C,OAAO,CAAC,WAAW;CA0BpB;AAQD,qBAAa,kBAAkB;IAK3B,OAAO,CAAC,QAAQ,CAAC,KAAK;IAJxB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;gBAG1C,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,EACP,KAAK,EAAE,WAAW;IAqB/B,GAAG,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,eAAe,CAAC;IAmB1D,GAAG,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,UAAU,CAAC;IAkBrD,MAAM,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBrD,IAAI,CAAC,KAAK,GAAE,sBAA2B,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAM7E"}
|
|
@@ -4,16 +4,34 @@ exports.ScopedObjectClient = exports.ObjectClient = void 0;
|
|
|
4
4
|
const node_stream_1 = require("node:stream");
|
|
5
5
|
const errors_js_1 = require("../../errors.js");
|
|
6
6
|
class ObjectClient {
|
|
7
|
-
constructor(apiClient) {
|
|
7
|
+
constructor(apiClient, defaultOwnerId, defaultRegion) {
|
|
8
8
|
this.apiClient = apiClient;
|
|
9
|
+
this.defaultOwnerId = defaultOwnerId;
|
|
10
|
+
this.defaultRegion = defaultRegion;
|
|
11
|
+
}
|
|
12
|
+
resolveOwnerId(ownerId) {
|
|
13
|
+
const resolved = ownerId || this.defaultOwnerId;
|
|
14
|
+
if (!resolved) {
|
|
15
|
+
throw new errors_js_1.RenderError("ownerId is required. Provide it as a parameter or set the RENDER_WORKSPACE_ID environment variable.");
|
|
16
|
+
}
|
|
17
|
+
return resolved;
|
|
18
|
+
}
|
|
19
|
+
resolveRegion(region) {
|
|
20
|
+
const resolved = region || this.defaultRegion;
|
|
21
|
+
if (!resolved) {
|
|
22
|
+
throw new errors_js_1.RenderError("region is required. Provide it as a parameter or set the RENDER_REGION environment variable.");
|
|
23
|
+
}
|
|
24
|
+
return resolved;
|
|
9
25
|
}
|
|
10
26
|
async put(input) {
|
|
27
|
+
const ownerId = this.resolveOwnerId(input.ownerId);
|
|
28
|
+
const region = this.resolveRegion(input.region);
|
|
11
29
|
const size = this.resolveSize(input);
|
|
12
30
|
const { data, error } = await this.apiClient.PUT("/objects/{ownerId}/{region}/{key}", {
|
|
13
31
|
params: {
|
|
14
32
|
path: {
|
|
15
|
-
ownerId
|
|
16
|
-
region:
|
|
33
|
+
ownerId,
|
|
34
|
+
region: region,
|
|
17
35
|
key: input.key,
|
|
18
36
|
},
|
|
19
37
|
},
|
|
@@ -53,11 +71,13 @@ class ObjectClient {
|
|
|
53
71
|
};
|
|
54
72
|
}
|
|
55
73
|
async get(input) {
|
|
74
|
+
const ownerId = this.resolveOwnerId(input.ownerId);
|
|
75
|
+
const region = this.resolveRegion(input.region);
|
|
56
76
|
const { data, error } = await this.apiClient.GET("/objects/{ownerId}/{region}/{key}", {
|
|
57
77
|
params: {
|
|
58
78
|
path: {
|
|
59
|
-
ownerId
|
|
60
|
-
region:
|
|
79
|
+
ownerId,
|
|
80
|
+
region: region,
|
|
61
81
|
key: input.key,
|
|
62
82
|
},
|
|
63
83
|
},
|
|
@@ -78,11 +98,13 @@ class ObjectClient {
|
|
|
78
98
|
};
|
|
79
99
|
}
|
|
80
100
|
async delete(input) {
|
|
101
|
+
const ownerId = this.resolveOwnerId(input.ownerId);
|
|
102
|
+
const region = this.resolveRegion(input.region);
|
|
81
103
|
const { error } = await this.apiClient.DELETE("/objects/{ownerId}/{region}/{key}", {
|
|
82
104
|
params: {
|
|
83
105
|
path: {
|
|
84
|
-
ownerId
|
|
85
|
-
region:
|
|
106
|
+
ownerId,
|
|
107
|
+
region: region,
|
|
86
108
|
key: input.key,
|
|
87
109
|
},
|
|
88
110
|
},
|
|
@@ -92,11 +114,13 @@ class ObjectClient {
|
|
|
92
114
|
}
|
|
93
115
|
}
|
|
94
116
|
async list(input) {
|
|
117
|
+
const ownerId = this.resolveOwnerId(input.ownerId);
|
|
118
|
+
const region = this.resolveRegion(input.region);
|
|
95
119
|
const { data, error } = await this.apiClient.GET("/objects/{ownerId}/{region}", {
|
|
96
120
|
params: {
|
|
97
121
|
path: {
|
|
98
|
-
ownerId
|
|
99
|
-
region:
|
|
122
|
+
ownerId,
|
|
123
|
+
region: region,
|
|
100
124
|
},
|
|
101
125
|
query: {
|
|
102
126
|
cursor: input.cursor,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"e2e-helpers.d.ts","sourceRoot":"","sources":["../../../src/experimental/object/e2e-helpers.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAchD,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,OAAO,MAAM,EAAE,EACxB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAsEjB"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.objectStorageCrudCheck = objectStorageCrudCheck;
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
const errors_js_1 = require("../../errors.js");
|
|
6
|
+
const RETRY_ATTEMPTS = 5;
|
|
7
|
+
const RETRY_INTERVAL_MS = 1000;
|
|
8
|
+
function sleep(ms) {
|
|
9
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
10
|
+
}
|
|
11
|
+
async function objectStorageCrudCheck(client, ownerId, region) {
|
|
12
|
+
const key = `e2e-test/${(0, node_crypto_1.randomUUID)()}/crud-test.txt`;
|
|
13
|
+
const content = Buffer.from("hello from e2e");
|
|
14
|
+
try {
|
|
15
|
+
await client.put({
|
|
16
|
+
ownerId,
|
|
17
|
+
region,
|
|
18
|
+
key,
|
|
19
|
+
data: content,
|
|
20
|
+
});
|
|
21
|
+
let found = false;
|
|
22
|
+
for (let attempt = 1; attempt <= RETRY_ATTEMPTS; attempt++) {
|
|
23
|
+
const listResponse = await client.list({ ownerId, region });
|
|
24
|
+
const match = listResponse.objects.find((o) => o.key === key);
|
|
25
|
+
if (match) {
|
|
26
|
+
if (match.size !== content.byteLength) {
|
|
27
|
+
throw new Error(`LIST size mismatch: expected ${content.byteLength}, got ${match.size}`);
|
|
28
|
+
}
|
|
29
|
+
const age = Date.now() - match.lastModified.getTime();
|
|
30
|
+
if (age > 5 * 60 * 1000) {
|
|
31
|
+
throw new Error(`LIST lastModified too old: ${match.lastModified.toISOString()}`);
|
|
32
|
+
}
|
|
33
|
+
found = true;
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
if (attempt < RETRY_ATTEMPTS) {
|
|
37
|
+
await sleep(RETRY_INTERVAL_MS);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (!found) {
|
|
41
|
+
throw new Error(`Object ${key} not found in LIST after ${RETRY_ATTEMPTS} attempts`);
|
|
42
|
+
}
|
|
43
|
+
const obj = await client.get({ ownerId, region, key });
|
|
44
|
+
if (!obj.data.equals(content)) {
|
|
45
|
+
throw new Error("GET data does not match uploaded content");
|
|
46
|
+
}
|
|
47
|
+
if (obj.size !== content.byteLength) {
|
|
48
|
+
throw new Error(`GET size mismatch: expected ${content.byteLength}, got ${obj.size}`);
|
|
49
|
+
}
|
|
50
|
+
await client.delete({ ownerId, region, key });
|
|
51
|
+
try {
|
|
52
|
+
await client.get({ ownerId, region, key });
|
|
53
|
+
throw new Error("GET after DELETE should have thrown");
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
if (!(err instanceof errors_js_1.RenderError)) {
|
|
57
|
+
throw err;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return key;
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
try {
|
|
64
|
+
await client.delete({ ownerId, region, key });
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
}
|
|
68
|
+
throw err;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -38,6 +38,7 @@ export interface ObjectData {
|
|
|
38
38
|
export interface PutObjectResult {
|
|
39
39
|
etag?: string;
|
|
40
40
|
}
|
|
41
|
+
export type OptionalScope<T> = Omit<T, keyof ObjectScope> & Partial<ObjectScope>;
|
|
41
42
|
export interface ObjectScope {
|
|
42
43
|
ownerId: `tea-${string}`;
|
|
43
44
|
region: Region | string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/experimental/object/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAK5C,MAAM,MAAM,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,CAAC;AAKhF,MAAM,WAAW,gBAAgB;IAE/B,OAAO,EAAE,OAAO,MAAM,EAAE,CAAC;IAEzB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAExB,GAAG,EAAE,MAAM,CAAC;CACb;AAKD,UAAU,kBAAmB,SAAQ,gBAAgB;IAEnD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAMD,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAE9D,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;IAEnC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAMD,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAE9D,IAAI,EAAE,QAAQ,CAAC;IAEf,IAAI,EAAE,MAAM,CAAC;CACd;AAMD,MAAM,MAAM,cAAc,GAAG,oBAAoB,GAAG,oBAAoB,CAAC;AAKzE,MAAM,WAAW,cAAe,SAAQ,gBAAgB;CAAG;AAK3D,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;CAAG;AAK9D,MAAM,WAAW,kBAAkB;IAEjC,GAAG,EAAE,MAAM,CAAC;IAEZ,SAAS,EAAE,IAAI,CAAC;IAEhB,YAAY,EAAE,MAAM,CAAC;CACtB;AAKD,MAAM,WAAW,oBAAoB;IAEnC,GAAG,EAAE,MAAM,CAAC;IAEZ,SAAS,EAAE,IAAI,CAAC;CACjB;AAKD,MAAM,WAAW,UAAU;IAEzB,IAAI,EAAE,MAAM,CAAC;IAEb,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,IAAI,EAAE,MAAM,CAAC;CACd;AAKD,MAAM,WAAW,eAAe;IAE9B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/experimental/object/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAK5C,MAAM,MAAM,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,CAAC;AAKhF,MAAM,WAAW,gBAAgB;IAE/B,OAAO,EAAE,OAAO,MAAM,EAAE,CAAC;IAEzB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAExB,GAAG,EAAE,MAAM,CAAC;CACb;AAKD,UAAU,kBAAmB,SAAQ,gBAAgB;IAEnD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAMD,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAE9D,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;IAEnC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAMD,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAE9D,IAAI,EAAE,QAAQ,CAAC;IAEf,IAAI,EAAE,MAAM,CAAC;CACd;AAMD,MAAM,MAAM,cAAc,GAAG,oBAAoB,GAAG,oBAAoB,CAAC;AAKzE,MAAM,WAAW,cAAe,SAAQ,gBAAgB;CAAG;AAK3D,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;CAAG;AAK9D,MAAM,WAAW,kBAAkB;IAEjC,GAAG,EAAE,MAAM,CAAC;IAEZ,SAAS,EAAE,IAAI,CAAC;IAEhB,YAAY,EAAE,MAAM,CAAC;CACtB;AAKD,MAAM,WAAW,oBAAoB;IAEnC,GAAG,EAAE,MAAM,CAAC;IAEZ,SAAS,EAAE,IAAI,CAAC;CACjB;AAKD,MAAM,WAAW,UAAU;IAEzB,IAAI,EAAE,MAAM,CAAC;IAEb,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,IAAI,EAAE,MAAM,CAAC;CACd;AAKD,MAAM,WAAW,eAAe;IAE9B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAMD,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,MAAM,WAAW,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AAKjF,MAAM,WAAW,WAAW;IAE1B,OAAO,EAAE,OAAO,MAAM,EAAE,CAAC;IAEzB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAKD,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,cAAc,EAAE,MAAM,WAAW,CAAC,CAAC;AAK3E,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,cAAc,EAAE,MAAM,WAAW,CAAC,CAAC;AAK3E,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,iBAAiB,EAAE,MAAM,WAAW,CAAC,CAAC;AAKjF,MAAM,WAAW,gBAAgB;IAE/B,OAAO,EAAE,OAAO,MAAM,EAAE,CAAC;IAEzB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAExB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,gBAAgB,EAAE,MAAM,WAAW,CAAC,CAAC;AAK/E,MAAM,WAAW,cAAc;IAE7B,GAAG,EAAE,MAAM,CAAC;IAEZ,IAAI,EAAE,MAAM,CAAC;IAEb,YAAY,EAAE,IAAI,CAAC;CACpB;AAKD,MAAM,WAAW,mBAAmB;IAElC,OAAO,EAAE,cAAc,EAAE,CAAC;IAE1B,OAAO,EAAE,OAAO,CAAC;IAEjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
|
package/dist/render.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAIpE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAKjE,qBAAa,MAAM;IACjB,SAAgB,SAAS,EAAE,eAAe,CAAC;IAC3C,SAAgB,YAAY,EAAE,kBAAkB,CAAC;IAEjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;gBAM9B,OAAO,CAAC,EAAE,aAAa;
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAIpE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAKjE,qBAAa,MAAM;IACjB,SAAgB,SAAS,EAAE,eAAe,CAAC;IAC3C,SAAgB,YAAY,EAAE,kBAAkB,CAAC;IAEjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;gBAM9B,OAAO,CAAC,EAAE,aAAa;CAepC"}
|
package/dist/render.js
CHANGED
|
@@ -15,7 +15,9 @@ class Render {
|
|
|
15
15
|
const baseUrl = (0, get_base_url_js_1.getBaseUrl)(options);
|
|
16
16
|
this.apiClient = (0, create_api_client_js_1.createApiClient)(baseUrl, token);
|
|
17
17
|
this.workflows = new index_js_1.WorkflowsClient(this.apiClient, baseUrl, token);
|
|
18
|
-
|
|
18
|
+
const defaultOwnerId = options?.ownerId || process.env.RENDER_WORKSPACE_ID || undefined;
|
|
19
|
+
const defaultRegion = options?.region || process.env.RENDER_REGION || undefined;
|
|
20
|
+
this.experimental = new experimental_js_1.ExperimentalClient(this.apiClient, defaultOwnerId, defaultRegion);
|
|
19
21
|
}
|
|
20
22
|
}
|
|
21
23
|
exports.Render = Render;
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import type { Client as ApiClient } from "openapi-fetch";
|
|
2
2
|
import type { paths } from "../../generated/schema.js";
|
|
3
|
+
import { TaskRunResult } from "./task-run-result.js";
|
|
3
4
|
import type { ListTaskRunsParams, TaskData, TaskIdentifier, TaskRun, TaskRunDetails } from "./types.js";
|
|
4
5
|
export declare class WorkflowsClient {
|
|
5
|
-
private readonly sse;
|
|
6
6
|
private readonly apiClient;
|
|
7
|
+
private readonly baseUrl;
|
|
8
|
+
private readonly token;
|
|
7
9
|
constructor(apiClient: ApiClient<paths>, baseUrl: string, token: string);
|
|
10
|
+
taskRunEvents(taskRunIds: string[], signal?: AbortSignal): AsyncGenerator<TaskRunDetails>;
|
|
11
|
+
startTask(taskIdentifier: TaskIdentifier, inputData: TaskData, signal?: AbortSignal): Promise<TaskRunResult>;
|
|
8
12
|
runTask(taskIdentifier: TaskIdentifier, inputData: TaskData, signal?: AbortSignal): Promise<TaskRunDetails>;
|
|
9
|
-
private waitForTask;
|
|
10
13
|
getTaskRun(taskRunId: string): Promise<TaskRunDetails>;
|
|
11
|
-
|
|
14
|
+
cancelTaskRun(taskRunId: string): Promise<void>;
|
|
12
15
|
listTaskRuns(params: ListTaskRunsParams): Promise<TaskRun[]>;
|
|
16
|
+
private waitOnTaskRun;
|
|
13
17
|
}
|
|
14
18
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/workflows/client/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/workflows/client/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAGvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EACV,kBAAkB,EAClB,QAAQ,EACR,cAAc,EACd,OAAO,EACP,cAAc,EACf,MAAM,YAAY,CAAC;AAoBpB,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmB;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAOnB,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAchE,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,cAAc,CAAC,cAAc,CAAC;IA0G1F,SAAS,CACb,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAE,QAAQ,EACnB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,aAAa,CAAC;IA+BnB,OAAO,CACX,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAE,QAAQ,EACnB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,cAAc,CAAC;IAWpB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IActD,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe/C,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;YAcpD,aAAa;CAM5B"}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.WorkflowsClient = void 0;
|
|
4
|
+
const eventsource_1 = require("eventsource");
|
|
4
5
|
const errors_js_1 = require("../../errors.js");
|
|
6
|
+
const version_js_1 = require("../../version.js");
|
|
5
7
|
const sse_js_1 = require("./sse.js");
|
|
8
|
+
const task_run_result_js_1 = require("./task-run-result.js");
|
|
6
9
|
function handleApiError(error, response, context) {
|
|
7
10
|
const statusCode = response.status;
|
|
8
11
|
const errorMessage = `${context}: ${error}`;
|
|
@@ -16,22 +19,97 @@ function handleApiError(error, response, context) {
|
|
|
16
19
|
}
|
|
17
20
|
class WorkflowsClient {
|
|
18
21
|
constructor(apiClient, baseUrl, token) {
|
|
19
|
-
this.sse = new sse_js_1.SSEClient(baseUrl, token);
|
|
20
22
|
this.apiClient = apiClient;
|
|
23
|
+
this.baseUrl = baseUrl;
|
|
24
|
+
this.token = token;
|
|
21
25
|
}
|
|
22
|
-
async
|
|
26
|
+
async *taskRunEvents(taskRunIds, signal) {
|
|
23
27
|
if (signal?.aborted) {
|
|
24
28
|
throw new errors_js_1.AbortError();
|
|
25
29
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
const queue = [];
|
|
31
|
+
let resolve = null;
|
|
32
|
+
let finished = false;
|
|
33
|
+
let streamError = null;
|
|
34
|
+
const push = (item) => {
|
|
35
|
+
queue.push(item);
|
|
36
|
+
if (resolve) {
|
|
37
|
+
resolve();
|
|
38
|
+
resolve = null;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const fail = (err) => {
|
|
42
|
+
streamError = err;
|
|
43
|
+
finished = true;
|
|
44
|
+
if (resolve) {
|
|
45
|
+
resolve();
|
|
46
|
+
resolve = null;
|
|
31
47
|
}
|
|
32
48
|
};
|
|
49
|
+
const url = new URL("/v1/task-runs/events", this.baseUrl);
|
|
50
|
+
url.searchParams.append("taskRunIds", taskRunIds.join(","));
|
|
51
|
+
const eventSource = new eventsource_1.EventSource(url.toString(), {
|
|
52
|
+
fetch: (input, init) => fetch(input, {
|
|
53
|
+
...init,
|
|
54
|
+
headers: {
|
|
55
|
+
...init?.headers,
|
|
56
|
+
Authorization: `Bearer ${this.token}`,
|
|
57
|
+
"User-Agent": (0, version_js_1.getUserAgent)(),
|
|
58
|
+
},
|
|
59
|
+
}),
|
|
60
|
+
});
|
|
61
|
+
const eventHandler = (event) => {
|
|
62
|
+
try {
|
|
63
|
+
const details = JSON.parse(event.data);
|
|
64
|
+
push(details);
|
|
65
|
+
}
|
|
66
|
+
catch (e) {
|
|
67
|
+
fail(new Error(`Failed to parse task run details: ${e}`));
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const errorHandler = (error) => {
|
|
71
|
+
fail(new Error(`SSE connection error: ${error.message || "Unknown error"}`));
|
|
72
|
+
};
|
|
73
|
+
const abortHandler = () => {
|
|
74
|
+
cleanup();
|
|
75
|
+
fail(new errors_js_1.AbortError());
|
|
76
|
+
};
|
|
77
|
+
const cleanup = () => {
|
|
78
|
+
eventSource.removeEventListener(sse_js_1.TaskEventType.COMPLETED, eventHandler);
|
|
79
|
+
eventSource.removeEventListener(sse_js_1.TaskEventType.FAILED, eventHandler);
|
|
80
|
+
eventSource.removeEventListener("error", errorHandler);
|
|
81
|
+
eventSource.close();
|
|
82
|
+
signal?.removeEventListener("abort", abortHandler);
|
|
83
|
+
};
|
|
84
|
+
eventSource.addEventListener(sse_js_1.TaskEventType.COMPLETED, eventHandler);
|
|
85
|
+
eventSource.addEventListener(sse_js_1.TaskEventType.FAILED, eventHandler);
|
|
86
|
+
eventSource.addEventListener("error", errorHandler);
|
|
87
|
+
signal?.addEventListener("abort", abortHandler);
|
|
88
|
+
try {
|
|
89
|
+
while (true) {
|
|
90
|
+
while (queue.length > 0) {
|
|
91
|
+
yield queue.shift();
|
|
92
|
+
}
|
|
93
|
+
if (finished) {
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
await new Promise((r) => {
|
|
97
|
+
resolve = r;
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
if (streamError) {
|
|
101
|
+
throw streamError;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
finally {
|
|
105
|
+
cleanup();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async startTask(taskIdentifier, inputData, signal) {
|
|
109
|
+
if (signal?.aborted) {
|
|
110
|
+
throw new errors_js_1.AbortError();
|
|
111
|
+
}
|
|
33
112
|
try {
|
|
34
|
-
signal?.addEventListener("abort", abortHandler);
|
|
35
113
|
const { data, error, response } = await this.apiClient.POST("/task-runs", {
|
|
36
114
|
body: {
|
|
37
115
|
task: taskIdentifier,
|
|
@@ -42,8 +120,7 @@ class WorkflowsClient {
|
|
|
42
120
|
if (error) {
|
|
43
121
|
handleApiError(error, response, "Failed to run task");
|
|
44
122
|
}
|
|
45
|
-
|
|
46
|
-
return await this.waitForTask(data.id, signal);
|
|
123
|
+
return new task_run_result_js_1.TaskRunResult((id, sig) => this.waitOnTaskRun(id, sig), data.id, signal);
|
|
47
124
|
}
|
|
48
125
|
catch (err) {
|
|
49
126
|
if (err instanceof DOMException && err.name === "AbortError") {
|
|
@@ -51,12 +128,10 @@ class WorkflowsClient {
|
|
|
51
128
|
}
|
|
52
129
|
throw err;
|
|
53
130
|
}
|
|
54
|
-
finally {
|
|
55
|
-
signal?.removeEventListener("abort", abortHandler);
|
|
56
|
-
}
|
|
57
131
|
}
|
|
58
|
-
async
|
|
59
|
-
|
|
132
|
+
async runTask(taskIdentifier, inputData, signal) {
|
|
133
|
+
const result = await this.startTask(taskIdentifier, inputData, signal);
|
|
134
|
+
return result.get();
|
|
60
135
|
}
|
|
61
136
|
async getTaskRun(taskRunId) {
|
|
62
137
|
const { data, error, response } = await this.apiClient.GET("/task-runs/{taskRunId}", {
|
|
@@ -84,5 +159,11 @@ class WorkflowsClient {
|
|
|
84
159
|
}
|
|
85
160
|
return data;
|
|
86
161
|
}
|
|
162
|
+
async waitOnTaskRun(taskRunId, signal) {
|
|
163
|
+
for await (const event of this.taskRunEvents([taskRunId], signal)) {
|
|
164
|
+
return event;
|
|
165
|
+
}
|
|
166
|
+
throw new Error(`SSE stream ended without receiving an event for task run ${taskRunId}`);
|
|
167
|
+
}
|
|
87
168
|
}
|
|
88
169
|
exports.WorkflowsClient = WorkflowsClient;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { WorkflowsClient } from "./client.js";
|
|
2
2
|
export { createWorkflowsClient } from "./create-client.js";
|
|
3
|
+
export { TaskEventType } from "./sse.js";
|
|
4
|
+
export { TaskRunResult } from "./task-run-result.js";
|
|
3
5
|
export * from "./types.js";
|
|
4
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/workflows/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/workflows/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,cAAc,YAAY,CAAC"}
|
|
@@ -14,9 +14,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.createWorkflowsClient = exports.WorkflowsClient = void 0;
|
|
17
|
+
exports.TaskRunResult = exports.TaskEventType = exports.createWorkflowsClient = exports.WorkflowsClient = void 0;
|
|
18
18
|
var client_js_1 = require("./client.js");
|
|
19
19
|
Object.defineProperty(exports, "WorkflowsClient", { enumerable: true, get: function () { return client_js_1.WorkflowsClient; } });
|
|
20
20
|
var create_client_js_1 = require("./create-client.js");
|
|
21
21
|
Object.defineProperty(exports, "createWorkflowsClient", { enumerable: true, get: function () { return create_client_js_1.createWorkflowsClient; } });
|
|
22
|
+
var sse_js_1 = require("./sse.js");
|
|
23
|
+
Object.defineProperty(exports, "TaskEventType", { enumerable: true, get: function () { return sse_js_1.TaskEventType; } });
|
|
24
|
+
var task_run_result_js_1 = require("./task-run-result.js");
|
|
25
|
+
Object.defineProperty(exports, "TaskRunResult", { enumerable: true, get: function () { return task_run_result_js_1.TaskRunResult; } });
|
|
22
26
|
__exportStar(require("./types.js"), exports);
|
|
@@ -1,14 +1,7 @@
|
|
|
1
|
-
import type { TaskRunDetails } from "./types.js";
|
|
2
1
|
export declare enum TaskEventType {
|
|
3
2
|
COMPLETED = "task.completed",
|
|
4
3
|
FAILED = "task.failed",
|
|
5
4
|
RUNNING = "task.running",
|
|
6
5
|
PENDING = "task.pending"
|
|
7
6
|
}
|
|
8
|
-
export declare class SSEClient {
|
|
9
|
-
private readonly baseUrl;
|
|
10
|
-
private readonly token;
|
|
11
|
-
constructor(baseUrl: string, token: string);
|
|
12
|
-
waitOnTaskRun(taskRunId: string, signal?: AbortSignal): Promise<TaskRunDetails>;
|
|
13
|
-
}
|
|
14
7
|
//# sourceMappingURL=sse.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../../src/workflows/client/sse.ts"],"names":[],"mappings":"AAGA,
|
|
1
|
+
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../../src/workflows/client/sse.ts"],"names":[],"mappings":"AAGA,oBAAY,aAAa;IACvB,SAAS,mBAAmB;IAC5B,MAAM,gBAAgB;IACtB,OAAO,iBAAiB;IACxB,OAAO,iBAAiB;CACzB"}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const eventsource_1 = require("eventsource");
|
|
5
|
-
const errors_js_1 = require("../../errors.js");
|
|
6
|
-
const version_js_1 = require("../../version.js");
|
|
3
|
+
exports.TaskEventType = void 0;
|
|
7
4
|
var TaskEventType;
|
|
8
5
|
(function (TaskEventType) {
|
|
9
6
|
TaskEventType["COMPLETED"] = "task.completed";
|
|
@@ -11,70 +8,3 @@ var TaskEventType;
|
|
|
11
8
|
TaskEventType["RUNNING"] = "task.running";
|
|
12
9
|
TaskEventType["PENDING"] = "task.pending";
|
|
13
10
|
})(TaskEventType || (exports.TaskEventType = TaskEventType = {}));
|
|
14
|
-
class SSEClient {
|
|
15
|
-
constructor(baseUrl, token) {
|
|
16
|
-
this.baseUrl = baseUrl;
|
|
17
|
-
this.token = token;
|
|
18
|
-
}
|
|
19
|
-
async waitOnTaskRun(taskRunId, signal) {
|
|
20
|
-
return new Promise((resolve, reject) => {
|
|
21
|
-
let eventSource = null;
|
|
22
|
-
const abortHandler = () => {
|
|
23
|
-
cleanup();
|
|
24
|
-
reject(new errors_js_1.AbortError());
|
|
25
|
-
};
|
|
26
|
-
const cleanup = () => {
|
|
27
|
-
if (eventSource) {
|
|
28
|
-
eventSource.removeEventListener(TaskEventType.COMPLETED, eventHandler);
|
|
29
|
-
eventSource.removeEventListener(TaskEventType.FAILED, eventHandler);
|
|
30
|
-
eventSource.removeEventListener("error", errorHandler);
|
|
31
|
-
eventSource.close();
|
|
32
|
-
eventSource = null;
|
|
33
|
-
}
|
|
34
|
-
signal?.removeEventListener("abort", abortHandler);
|
|
35
|
-
};
|
|
36
|
-
const eventHandler = (event) => {
|
|
37
|
-
try {
|
|
38
|
-
const details = JSON.parse(event.data);
|
|
39
|
-
cleanup();
|
|
40
|
-
resolve(details);
|
|
41
|
-
}
|
|
42
|
-
catch (e) {
|
|
43
|
-
cleanup();
|
|
44
|
-
reject(new Error(`Failed to parse task run details: ${e}`));
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
const errorHandler = (error) => {
|
|
48
|
-
cleanup();
|
|
49
|
-
reject(new Error(`SSE connection error: ${error.message || "Unknown error"}`));
|
|
50
|
-
};
|
|
51
|
-
if (signal?.aborted) {
|
|
52
|
-
reject(new errors_js_1.AbortError());
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
signal?.addEventListener("abort", abortHandler);
|
|
56
|
-
try {
|
|
57
|
-
const url = new URL("/v1/task-runs/events", this.baseUrl);
|
|
58
|
-
url.searchParams.append("taskRunIds", taskRunId);
|
|
59
|
-
eventSource = new eventsource_1.EventSource(url.toString(), {
|
|
60
|
-
fetch: (input, init) => fetch(input, {
|
|
61
|
-
...init,
|
|
62
|
-
headers: {
|
|
63
|
-
...init?.headers,
|
|
64
|
-
Authorization: `Bearer ${this.token}`,
|
|
65
|
-
"User-Agent": (0, version_js_1.getUserAgent)(),
|
|
66
|
-
},
|
|
67
|
-
}),
|
|
68
|
-
});
|
|
69
|
-
eventSource.addEventListener(TaskEventType.COMPLETED, eventHandler);
|
|
70
|
-
eventSource.addEventListener(TaskEventType.FAILED, eventHandler);
|
|
71
|
-
eventSource.addEventListener("error", errorHandler);
|
|
72
|
-
}
|
|
73
|
-
catch (e) {
|
|
74
|
-
cleanup();
|
|
75
|
-
reject(e);
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
exports.SSEClient = SSEClient;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SSEClient } from "./sse.js";
|
|
2
|
+
import type { TaskRunDetails } from "./types.js";
|
|
3
|
+
export declare class TaskRunPromise implements PromiseLike<TaskRunDetails> {
|
|
4
|
+
private readonly sseClient;
|
|
5
|
+
private readonly postPromise;
|
|
6
|
+
private readonly signal?;
|
|
7
|
+
private resultPromise;
|
|
8
|
+
constructor(sseClient: SSEClient, postPromise: Promise<string>, signal?: AbortSignal);
|
|
9
|
+
get taskRunId(): Promise<string>;
|
|
10
|
+
then<TResult1 = TaskRunDetails, TResult2 = never>(onfulfilled?: ((value: TaskRunDetails) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=task-run-promise.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-run-promise.d.ts","sourceRoot":"","sources":["../../../src/workflows/client/task-run-promise.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAUjD,qBAAa,cAAe,YAAW,WAAW,CAAC,cAAc,CAAC;IAChE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkB;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAc;IACtC,OAAO,CAAC,aAAa,CAAwC;gBAEjD,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW;IAUpF,IAAI,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAE/B;IAED,IAAI,CAAC,QAAQ,GAAG,cAAc,EAAE,QAAQ,GAAG,KAAK,EAC9C,WAAW,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,cAAc,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,EAClF,UAAU,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,GAAG,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,GACtE,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;CAShC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TaskRunPromise = void 0;
|
|
4
|
+
class TaskRunPromise {
|
|
5
|
+
constructor(sseClient, postPromise, signal) {
|
|
6
|
+
this.resultPromise = null;
|
|
7
|
+
this.sseClient = sseClient;
|
|
8
|
+
this.postPromise = postPromise;
|
|
9
|
+
this.signal = signal;
|
|
10
|
+
this.postPromise.catch(() => { });
|
|
11
|
+
}
|
|
12
|
+
get taskRunId() {
|
|
13
|
+
return this.postPromise;
|
|
14
|
+
}
|
|
15
|
+
then(onfulfilled, onrejected) {
|
|
16
|
+
if (!this.resultPromise) {
|
|
17
|
+
this.resultPromise = this.postPromise.then((taskRunId) => this.sseClient.waitOnTaskRun(taskRunId, this.signal));
|
|
18
|
+
}
|
|
19
|
+
return this.resultPromise.then(onfulfilled, onrejected);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.TaskRunPromise = TaskRunPromise;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TaskRunDetails } from "./types.js";
|
|
2
|
+
export declare class TaskRunResult {
|
|
3
|
+
readonly taskRunId: string;
|
|
4
|
+
private readonly waitOnTaskRun;
|
|
5
|
+
private readonly signal?;
|
|
6
|
+
private resultPromise;
|
|
7
|
+
constructor(waitOnTaskRun: (taskRunId: string, signal?: AbortSignal) => Promise<TaskRunDetails>, taskRunId: string, signal?: AbortSignal);
|
|
8
|
+
get(): Promise<TaskRunDetails>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=task-run-result.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-run-result.d.ts","sourceRoot":"","sources":["../../../src/workflows/client/task-run-result.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,qBAAa,aAAa;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAGD;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAc;IACtC,OAAO,CAAC,aAAa,CAAwC;gBAG3D,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,cAAc,CAAC,EACnF,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,WAAW;IAOtB,GAAG,IAAI,OAAO,CAAC,cAAc,CAAC;CAM/B"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TaskRunResult = void 0;
|
|
4
|
+
class TaskRunResult {
|
|
5
|
+
constructor(waitOnTaskRun, taskRunId, signal) {
|
|
6
|
+
this.resultPromise = null;
|
|
7
|
+
this.waitOnTaskRun = waitOnTaskRun;
|
|
8
|
+
this.taskRunId = taskRunId;
|
|
9
|
+
this.signal = signal;
|
|
10
|
+
}
|
|
11
|
+
get() {
|
|
12
|
+
if (!this.resultPromise) {
|
|
13
|
+
this.resultPromise = this.waitOnTaskRun(this.taskRunId, this.signal);
|
|
14
|
+
}
|
|
15
|
+
return this.resultPromise;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.TaskRunResult = TaskRunResult;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/workflows/client/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAKhE,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC;AAKpC,MAAM,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;AAKlC,oBAAY,aAAa;IACvB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,SAAS,cAAc;IACvB,MAAM,WAAW;CAClB;AAMD,MAAM,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC;AAMvD,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,gBAAgB,CAAC,CAAC;AAKrE,MAAM,MAAM,kBAAkB,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC;AAKnF,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,QAAQ,CAAC;CACjB;AAKD,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/workflows/client/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAKhE,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC;AAKpC,MAAM,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;AAKlC,oBAAY,aAAa;IACvB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,SAAS,cAAc;IACvB,MAAM,WAAW;CAClB;AAMD,MAAM,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC;AAMvD,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,gBAAgB,CAAC,CAAC;AAKrE,MAAM,MAAM,kBAAkB,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC;AAKnF,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,QAAQ,CAAC;CACjB;AAKD,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
|
package/dist/workflows/uds.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uds.d.ts","sourceRoot":"","sources":["../../src/workflows/uds.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAEV,gBAAgB,EAEhB,wBAAwB,EAIxB,YAAY,EACb,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"uds.d.ts","sourceRoot":"","sources":["../../src/workflows/uds.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAEV,gBAAgB,EAEhB,wBAAwB,EAIxB,YAAY,EACb,MAAM,YAAY,CAAC;AAapB,qBAAa,SAAS;IACR,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,MAAM;IAKzC,QAAQ,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAI3C,OAAO,CAAC,iBAAiB;IAyBnB,YAAY,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO1D,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAa3D,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAUtE,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAa3C,OAAO;YAmCP,WAAW;CA2C1B"}
|
package/dist/workflows/uds.js
CHANGED
|
@@ -6,6 +6,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.UDSClient = void 0;
|
|
7
7
|
const node_http_1 = __importDefault(require("node:http"));
|
|
8
8
|
const version_js_1 = require("../version.js");
|
|
9
|
+
const UDS_MAX_RETRIES = 15;
|
|
10
|
+
const UDS_INITIAL_DELAY_MS = 250;
|
|
11
|
+
const UDS_BACKOFF_FACTOR = 2;
|
|
12
|
+
const UDS_MAX_DELAY_MS = 16000;
|
|
13
|
+
const CLIENT_ERROR_RE = /^HTTP 4\d{2}:/;
|
|
14
|
+
const RETRY_ERROR_RE = /^HTTP 429:/;
|
|
9
15
|
class UDSClient {
|
|
10
16
|
constructor(socketPath) {
|
|
11
17
|
this.socketPath = socketPath;
|
|
@@ -61,6 +67,27 @@ class UDSClient {
|
|
|
61
67
|
}
|
|
62
68
|
async request(path, method, body) {
|
|
63
69
|
const bodyString = body ? JSON.stringify(body) : "";
|
|
70
|
+
let lastError = new Error("UDS request failed");
|
|
71
|
+
for (let attempt = 0; attempt < UDS_MAX_RETRIES; attempt++) {
|
|
72
|
+
try {
|
|
73
|
+
return await this.requestOnce(path, method, bodyString);
|
|
74
|
+
}
|
|
75
|
+
catch (e) {
|
|
76
|
+
lastError = e instanceof Error ? e : new Error(String(e));
|
|
77
|
+
if (CLIENT_ERROR_RE.test(lastError.message) && !RETRY_ERROR_RE.test(lastError.message)) {
|
|
78
|
+
throw lastError;
|
|
79
|
+
}
|
|
80
|
+
if (attempt < UDS_MAX_RETRIES - 1) {
|
|
81
|
+
const delay = Math.min(UDS_INITIAL_DELAY_MS * UDS_BACKOFF_FACTOR ** attempt, UDS_MAX_DELAY_MS);
|
|
82
|
+
console.warn(`Request to Render failed (attempt ${attempt + 1}/${UDS_MAX_RETRIES}), ` +
|
|
83
|
+
`retrying in ${delay}ms: ${lastError.message}`);
|
|
84
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
throw lastError;
|
|
89
|
+
}
|
|
90
|
+
async requestOnce(path, method, bodyString) {
|
|
64
91
|
return new Promise((resolve, reject) => {
|
|
65
92
|
const req = node_http_1.default.request({
|
|
66
93
|
socketPath: this.socketPath,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { TaskRegistry } from "./registry.js";
|
|
2
|
+
import type { RegisterTaskOptions, Retry, TaskFunction } from "./types.js";
|
|
3
|
+
export interface WorkflowsOptions {
|
|
4
|
+
defaultRetry?: Retry;
|
|
5
|
+
defaultTimeout?: number;
|
|
6
|
+
defaultPlan?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class Workflows {
|
|
9
|
+
private readonly _registry;
|
|
10
|
+
private readonly _defaultRetry?;
|
|
11
|
+
private readonly _defaultTimeout?;
|
|
12
|
+
private readonly _defaultPlan?;
|
|
13
|
+
constructor(options?: WorkflowsOptions);
|
|
14
|
+
get registry(): TaskRegistry;
|
|
15
|
+
task<TArgs extends any[], TResult>(options: RegisterTaskOptions, func: TaskFunction<TArgs, TResult>): TaskFunction<TArgs, TResult>;
|
|
16
|
+
start(): Promise<void>;
|
|
17
|
+
static fromWorkflows(apps: Workflows[], options?: WorkflowsOptions): Workflows;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=workflows.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflows.d.ts","sourceRoot":"","sources":["../../src/workflows/workflows.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAG7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE3E,MAAM,WAAW,gBAAgB;IAC/B,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAWD,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAQ;IACvC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAS;gBAE3B,OAAO,CAAC,EAAE,gBAAgB;IAUtC,IAAI,QAAQ,IAAI,YAAY,CAE3B;IAQD,IAAI,CAAC,KAAK,SAAS,GAAG,EAAE,EAAE,OAAO,EAC/B,OAAO,EAAE,mBAAmB,EAC5B,IAAI,EAAE,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,GACjC,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC;IAyBzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5B,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS;CAgB/E"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Workflows = void 0;
|
|
4
|
+
const errors_js_1 = require("../errors.js");
|
|
5
|
+
const registry_js_1 = require("./registry.js");
|
|
6
|
+
const runner_js_1 = require("./runner.js");
|
|
7
|
+
const task_js_1 = require("./task.js");
|
|
8
|
+
class Workflows {
|
|
9
|
+
constructor(options) {
|
|
10
|
+
this._registry = new registry_js_1.TaskRegistry();
|
|
11
|
+
this._defaultRetry = options?.defaultRetry;
|
|
12
|
+
this._defaultTimeout = options?.defaultTimeout;
|
|
13
|
+
this._defaultPlan = options?.defaultPlan;
|
|
14
|
+
}
|
|
15
|
+
get registry() {
|
|
16
|
+
return this._registry;
|
|
17
|
+
}
|
|
18
|
+
task(options, func) {
|
|
19
|
+
const mergedOptions = {
|
|
20
|
+
...options,
|
|
21
|
+
retry: options.retry ?? this._defaultRetry,
|
|
22
|
+
timeoutSeconds: options.timeoutSeconds ?? this._defaultTimeout,
|
|
23
|
+
plan: options.plan ?? this._defaultPlan,
|
|
24
|
+
};
|
|
25
|
+
this._registry.register(func, mergedOptions);
|
|
26
|
+
return ((...args) => {
|
|
27
|
+
const context = (0, task_js_1.getCurrentContext)();
|
|
28
|
+
if (!context) {
|
|
29
|
+
return func(...args);
|
|
30
|
+
}
|
|
31
|
+
const result = context.executeTask(func, options.name, ...args);
|
|
32
|
+
return result.get();
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
async start() {
|
|
36
|
+
await (0, runner_js_1.startTaskServer)(this._registry);
|
|
37
|
+
}
|
|
38
|
+
static fromWorkflows(apps, options) {
|
|
39
|
+
const combined = new Workflows(options);
|
|
40
|
+
for (const app of apps) {
|
|
41
|
+
for (const task of app._registry.getAllTasks()) {
|
|
42
|
+
if (combined._registry.has(task.name)) {
|
|
43
|
+
throw new errors_js_1.RenderError(`Duplicate task name '${task.name}' when combining workflows`);
|
|
44
|
+
}
|
|
45
|
+
combined._registry.registerMetadata(task);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return combined;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.Workflows = Workflows;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@renderinc/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Render SDK for TypeScript",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "tsc -p tsconfig.build.json",
|
|
12
12
|
"test": "vitest",
|
|
13
|
+
"test:e2e": "vitest run --config vitest.config.e2e.ts",
|
|
13
14
|
"typecheck": "tsc --noEmit",
|
|
14
15
|
"lint": "biome lint",
|
|
15
16
|
"lint:fix": "biome lint --write",
|