@mastra/client-js 0.1.14-alpha.1 → 0.1.14-alpha.3

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @mastra/client-js@0.1.14-alpha.1 build /home/runner/work/mastra/mastra/client-sdks/client-js
2
+ > @mastra/client-js@0.1.14-alpha.3 build /home/runner/work/mastra/mastra/client-sdks/client-js
3
3
  > tsup src/index.ts --format esm,cjs --dts --clean --treeshake=smallest --splitting
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -9,11 +9,11 @@
9
9
  CLI Cleaning output folder
10
10
  ESM Build start
11
11
  CJS Build start
12
- ESM dist/index.js 21.61 KB
13
- ESM ⚡️ Build success in 859ms
14
- CJS dist/index.cjs 21.79 KB
15
- CJS ⚡️ Build success in 860ms
12
+ ESM dist/index.js 21.30 KB
13
+ ESM ⚡️ Build success in 809ms
14
+ CJS dist/index.cjs 21.48 KB
15
+ CJS ⚡️ Build success in 810ms
16
16
  DTS Build start
17
- DTS ⚡️ Build success in 12860ms
18
- DTS dist/index.d.ts 18.89 KB
19
- DTS dist/index.d.cts 18.89 KB
17
+ DTS ⚡️ Build success in 12001ms
18
+ DTS dist/index.d.ts 18.97 KB
19
+ DTS dist/index.d.cts 18.97 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # @mastra/client-js
2
2
 
3
+ ## 0.1.14-alpha.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 789bef3: Make runId optional for workflow startAsync api
8
+ - 8393832: Handle nested workflow view on workflow graph
9
+ - Updated dependencies [5ae0180]
10
+ - Updated dependencies [9bfa12b]
11
+ - Updated dependencies [515ebfb]
12
+ - Updated dependencies [88fa727]
13
+ - Updated dependencies [f37f535]
14
+ - Updated dependencies [4d67826]
15
+ - Updated dependencies [6330967]
16
+ - Updated dependencies [8393832]
17
+ - Updated dependencies [6330967]
18
+ - @mastra/core@0.8.0-alpha.3
19
+
20
+ ## 0.1.14-alpha.2
21
+
22
+ ### Patch Changes
23
+
24
+ - 84fe241: Improve streaming of workflows
25
+ - Updated dependencies [56c31b7]
26
+ - Updated dependencies [dbbbf80]
27
+ - Updated dependencies [99d43b9]
28
+ - @mastra/core@0.8.0-alpha.2
29
+
3
30
  ## 0.1.14-alpha.1
4
31
 
5
32
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -359,6 +359,7 @@ var Vector = class extends BaseResource {
359
359
  };
360
360
 
361
361
  // src/resources/workflow.ts
362
+ var RECORD_SEPARATOR = "";
362
363
  var Workflow = class extends BaseResource {
363
364
  constructor(options, workflowId) {
364
365
  super(options);
@@ -372,6 +373,7 @@ var Workflow = class extends BaseResource {
372
373
  return this.request(`/api/workflows/${this.workflowId}`);
373
374
  }
374
375
  /**
376
+ * @deprecated Use `startAsync` instead
375
377
  * Executes the workflow with the provided parameters
376
378
  * @param params - Parameters required for workflow execution
377
379
  * @returns Promise containing the workflow execution results
@@ -428,11 +430,15 @@ var Workflow = class extends BaseResource {
428
430
  }
429
431
  /**
430
432
  * Starts a workflow run asynchronously and returns a promise that resolves when the workflow is complete
431
- * @param params - Object containing the runId and triggerData
433
+ * @param params - Object containing the optional runId and triggerData
432
434
  * @returns Promise containing the workflow execution results
433
435
  */
434
436
  startAsync(params) {
435
- return this.request(`/api/workflows/${this.workflowId}/startAsync?runId=${params.runId}`, {
437
+ const searchParams = new URLSearchParams();
438
+ if (!!params?.runId) {
439
+ searchParams.set("runId", params.runId);
440
+ }
441
+ return this.request(`/api/workflows/${this.workflowId}/start-async?${searchParams.toString()}`, {
436
442
  method: "POST",
437
443
  body: params?.triggerData
438
444
  });
@@ -443,7 +449,7 @@ var Workflow = class extends BaseResource {
443
449
  * @returns Promise containing the workflow resume results
444
450
  */
445
451
  resumeAsync(params) {
446
- return this.request(`/api/workflows/${this.workflowId}/resumeAsync?runId=${params.runId}`, {
452
+ return this.request(`/api/workflows/${this.workflowId}/resume-async?runId=${params.runId}`, {
447
453
  method: "POST",
448
454
  body: {
449
455
  stepId: params.stepId,
@@ -460,43 +466,34 @@ var Workflow = class extends BaseResource {
460
466
  */
461
467
  async *streamProcessor(stream) {
462
468
  const reader = stream.getReader();
469
+ let doneReading = false;
463
470
  let buffer = "";
464
471
  try {
465
- while (true) {
472
+ while (!doneReading) {
466
473
  const { done, value } = await reader.read();
467
- if (done) {
468
- if (buffer.trim().length > 0) {
469
- try {
470
- const record = JSON.parse(buffer);
471
- yield record;
472
- } catch (e) {
473
- console.warn("Could not parse final buffer content:", buffer);
474
+ doneReading = done;
475
+ if (done && !value) continue;
476
+ try {
477
+ const decoded = value ? new TextDecoder().decode(value) : "";
478
+ const chunks = (buffer + decoded).split(RECORD_SEPARATOR);
479
+ buffer = chunks.pop() || "";
480
+ for (const chunk of chunks) {
481
+ if (chunk) {
482
+ yield JSON.parse(chunk);
474
483
  }
475
484
  }
476
- break;
485
+ } catch (error) {
477
486
  }
478
- buffer += new TextDecoder().decode(value);
479
- const records = buffer.split("");
480
- buffer = records.pop() || "";
481
- for (const record of records) {
482
- if (record.trim().length > 0) {
483
- try {
484
- const parsedRecord = JSON.parse(record);
485
- const isWorkflowCompleted = Object.values(parsedRecord?.activePaths || {}).every(
486
- (path) => path.status === "completed" || path.status === "suspended" || path.status === "failed" || path.status === "skipped"
487
- );
488
- if (isWorkflowCompleted) {
489
- reader.cancel();
490
- }
491
- yield parsedRecord;
492
- } catch (e) {
493
- throw new Error(`Could not parse record: ${record}, ${e}`);
494
- }
495
- }
487
+ }
488
+ if (buffer) {
489
+ try {
490
+ yield JSON.parse(buffer);
491
+ } catch {
496
492
  }
497
493
  }
498
494
  } finally {
499
- reader.cancel();
495
+ reader.cancel().catch(() => {
496
+ });
500
497
  }
501
498
  }
502
499
  /**
package/dist/index.d.cts CHANGED
@@ -51,6 +51,7 @@ interface GetWorkflowResponse {
51
51
  steps: Record<string, StepAction<any, any, any, any>>;
52
52
  stepGraph: StepGraph;
53
53
  stepSubscriberGraph: Record<string, StepGraph>;
54
+ workflowId?: string;
54
55
  }
55
56
  type WorkflowRunResult = {
56
57
  activePaths: Record<string, {
@@ -339,6 +340,7 @@ declare class Workflow extends BaseResource {
339
340
  */
340
341
  details(): Promise<GetWorkflowResponse>;
341
342
  /**
343
+ * @deprecated Use `startAsync` instead
342
344
  * Executes the workflow with the provided parameters
343
345
  * @param params - Parameters required for workflow execution
344
346
  * @returns Promise containing the workflow execution results
@@ -380,11 +382,11 @@ declare class Workflow extends BaseResource {
380
382
  }>;
381
383
  /**
382
384
  * Starts a workflow run asynchronously and returns a promise that resolves when the workflow is complete
383
- * @param params - Object containing the runId and triggerData
385
+ * @param params - Object containing the optional runId and triggerData
384
386
  * @returns Promise containing the workflow execution results
385
387
  */
386
388
  startAsync(params: {
387
- runId: string;
389
+ runId?: string;
388
390
  triggerData: Record<string, any>;
389
391
  }): Promise<WorkflowRunResult>;
390
392
  /**
package/dist/index.d.ts CHANGED
@@ -51,6 +51,7 @@ interface GetWorkflowResponse {
51
51
  steps: Record<string, StepAction<any, any, any, any>>;
52
52
  stepGraph: StepGraph;
53
53
  stepSubscriberGraph: Record<string, StepGraph>;
54
+ workflowId?: string;
54
55
  }
55
56
  type WorkflowRunResult = {
56
57
  activePaths: Record<string, {
@@ -339,6 +340,7 @@ declare class Workflow extends BaseResource {
339
340
  */
340
341
  details(): Promise<GetWorkflowResponse>;
341
342
  /**
343
+ * @deprecated Use `startAsync` instead
342
344
  * Executes the workflow with the provided parameters
343
345
  * @param params - Parameters required for workflow execution
344
346
  * @returns Promise containing the workflow execution results
@@ -380,11 +382,11 @@ declare class Workflow extends BaseResource {
380
382
  }>;
381
383
  /**
382
384
  * Starts a workflow run asynchronously and returns a promise that resolves when the workflow is complete
383
- * @param params - Object containing the runId and triggerData
385
+ * @param params - Object containing the optional runId and triggerData
384
386
  * @returns Promise containing the workflow execution results
385
387
  */
386
388
  startAsync(params: {
387
- runId: string;
389
+ runId?: string;
388
390
  triggerData: Record<string, any>;
389
391
  }): Promise<WorkflowRunResult>;
390
392
  /**
package/dist/index.js CHANGED
@@ -357,6 +357,7 @@ var Vector = class extends BaseResource {
357
357
  };
358
358
 
359
359
  // src/resources/workflow.ts
360
+ var RECORD_SEPARATOR = "";
360
361
  var Workflow = class extends BaseResource {
361
362
  constructor(options, workflowId) {
362
363
  super(options);
@@ -370,6 +371,7 @@ var Workflow = class extends BaseResource {
370
371
  return this.request(`/api/workflows/${this.workflowId}`);
371
372
  }
372
373
  /**
374
+ * @deprecated Use `startAsync` instead
373
375
  * Executes the workflow with the provided parameters
374
376
  * @param params - Parameters required for workflow execution
375
377
  * @returns Promise containing the workflow execution results
@@ -426,11 +428,15 @@ var Workflow = class extends BaseResource {
426
428
  }
427
429
  /**
428
430
  * Starts a workflow run asynchronously and returns a promise that resolves when the workflow is complete
429
- * @param params - Object containing the runId and triggerData
431
+ * @param params - Object containing the optional runId and triggerData
430
432
  * @returns Promise containing the workflow execution results
431
433
  */
432
434
  startAsync(params) {
433
- return this.request(`/api/workflows/${this.workflowId}/startAsync?runId=${params.runId}`, {
435
+ const searchParams = new URLSearchParams();
436
+ if (!!params?.runId) {
437
+ searchParams.set("runId", params.runId);
438
+ }
439
+ return this.request(`/api/workflows/${this.workflowId}/start-async?${searchParams.toString()}`, {
434
440
  method: "POST",
435
441
  body: params?.triggerData
436
442
  });
@@ -441,7 +447,7 @@ var Workflow = class extends BaseResource {
441
447
  * @returns Promise containing the workflow resume results
442
448
  */
443
449
  resumeAsync(params) {
444
- return this.request(`/api/workflows/${this.workflowId}/resumeAsync?runId=${params.runId}`, {
450
+ return this.request(`/api/workflows/${this.workflowId}/resume-async?runId=${params.runId}`, {
445
451
  method: "POST",
446
452
  body: {
447
453
  stepId: params.stepId,
@@ -458,43 +464,34 @@ var Workflow = class extends BaseResource {
458
464
  */
459
465
  async *streamProcessor(stream) {
460
466
  const reader = stream.getReader();
467
+ let doneReading = false;
461
468
  let buffer = "";
462
469
  try {
463
- while (true) {
470
+ while (!doneReading) {
464
471
  const { done, value } = await reader.read();
465
- if (done) {
466
- if (buffer.trim().length > 0) {
467
- try {
468
- const record = JSON.parse(buffer);
469
- yield record;
470
- } catch (e) {
471
- console.warn("Could not parse final buffer content:", buffer);
472
+ doneReading = done;
473
+ if (done && !value) continue;
474
+ try {
475
+ const decoded = value ? new TextDecoder().decode(value) : "";
476
+ const chunks = (buffer + decoded).split(RECORD_SEPARATOR);
477
+ buffer = chunks.pop() || "";
478
+ for (const chunk of chunks) {
479
+ if (chunk) {
480
+ yield JSON.parse(chunk);
472
481
  }
473
482
  }
474
- break;
483
+ } catch (error) {
475
484
  }
476
- buffer += new TextDecoder().decode(value);
477
- const records = buffer.split("");
478
- buffer = records.pop() || "";
479
- for (const record of records) {
480
- if (record.trim().length > 0) {
481
- try {
482
- const parsedRecord = JSON.parse(record);
483
- const isWorkflowCompleted = Object.values(parsedRecord?.activePaths || {}).every(
484
- (path) => path.status === "completed" || path.status === "suspended" || path.status === "failed" || path.status === "skipped"
485
- );
486
- if (isWorkflowCompleted) {
487
- reader.cancel();
488
- }
489
- yield parsedRecord;
490
- } catch (e) {
491
- throw new Error(`Could not parse record: ${record}, ${e}`);
492
- }
493
- }
485
+ }
486
+ if (buffer) {
487
+ try {
488
+ yield JSON.parse(buffer);
489
+ } catch {
494
490
  }
495
491
  }
496
492
  } finally {
497
- reader.cancel();
493
+ reader.cancel().catch(() => {
494
+ });
498
495
  }
499
496
  }
500
497
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/client-js",
3
- "version": "0.1.14-alpha.1",
3
+ "version": "0.1.14-alpha.3",
4
4
  "description": "The official TypeScript library for the Mastra Client API",
5
5
  "author": "",
6
6
  "type": "module",
@@ -26,11 +26,11 @@
26
26
  "json-schema": "^0.4.0",
27
27
  "zod": "^3.24.2",
28
28
  "zod-to-json-schema": "^3.24.3",
29
- "@mastra/core": "^0.8.0-alpha.1"
29
+ "@mastra/core": "^0.8.0-alpha.3"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@babel/preset-env": "^7.26.9",
33
- "@babel/preset-typescript": "^7.26.0",
33
+ "@babel/preset-typescript": "^7.27.0",
34
34
  "@tsconfig/recommended": "^1.0.8",
35
35
  "@types/json-schema": "^7.0.15",
36
36
  "@types/node": "^20.17.27",
package/src/index.test.ts CHANGED
@@ -12,6 +12,7 @@ describe('MastraClient Resources', () => {
12
12
  baseUrl: 'http://localhost:4111',
13
13
  headers: {
14
14
  Authorization: 'Bearer test-key',
15
+ 'x-mastra-client-type': 'js',
15
16
  },
16
17
  };
17
18
 
@@ -631,14 +632,14 @@ describe('MastraClient Resources', () => {
631
632
  };
632
633
  mockFetchResponse(mockResponse);
633
634
 
634
- const result = await workflow.execute({ trigger: 'test' });
635
+ const result = await workflow.startAsync({ triggerData: { test: 'test' } });
635
636
  expect(result).toEqual(mockResponse);
636
637
  expect(global.fetch).toHaveBeenCalledWith(
637
- `${clientOptions.baseUrl}/api/workflows/test-workflow/execute`,
638
+ `${clientOptions.baseUrl}/api/workflows/test-workflow/start-async?`,
638
639
  expect.objectContaining({
639
640
  method: 'POST',
640
641
  headers: expect.objectContaining(clientOptions.headers),
641
- body: JSON.stringify({ trigger: 'test' }),
642
+ body: JSON.stringify({ test: 'test' }),
642
643
  }),
643
644
  );
644
645
  });
@@ -2,6 +2,8 @@ import type { GetWorkflowResponse, ClientOptions, WorkflowRunResult } from '../t
2
2
 
3
3
  import { BaseResource } from './base';
4
4
 
5
+ const RECORD_SEPARATOR = '\x1E';
6
+
5
7
  export class Workflow extends BaseResource {
6
8
  constructor(
7
9
  options: ClientOptions,
@@ -19,6 +21,7 @@ export class Workflow extends BaseResource {
19
21
  }
20
22
 
21
23
  /**
24
+ * @deprecated Use `startAsync` instead
22
25
  * Executes the workflow with the provided parameters
23
26
  * @param params - Parameters required for workflow execution
24
27
  * @returns Promise containing the workflow execution results
@@ -85,11 +88,17 @@ export class Workflow extends BaseResource {
85
88
 
86
89
  /**
87
90
  * Starts a workflow run asynchronously and returns a promise that resolves when the workflow is complete
88
- * @param params - Object containing the runId and triggerData
91
+ * @param params - Object containing the optional runId and triggerData
89
92
  * @returns Promise containing the workflow execution results
90
93
  */
91
- startAsync(params: { runId: string; triggerData: Record<string, any> }): Promise<WorkflowRunResult> {
92
- return this.request(`/api/workflows/${this.workflowId}/startAsync?runId=${params.runId}`, {
94
+ startAsync(params: { runId?: string; triggerData: Record<string, any> }): Promise<WorkflowRunResult> {
95
+ const searchParams = new URLSearchParams();
96
+
97
+ if (!!params?.runId) {
98
+ searchParams.set('runId', params.runId);
99
+ }
100
+
101
+ return this.request(`/api/workflows/${this.workflowId}/start-async?${searchParams.toString()}`, {
93
102
  method: 'POST',
94
103
  body: params?.triggerData,
95
104
  });
@@ -101,7 +110,7 @@ export class Workflow extends BaseResource {
101
110
  * @returns Promise containing the workflow resume results
102
111
  */
103
112
  resumeAsync(params: { runId: string; stepId: string; context: Record<string, any> }): Promise<WorkflowRunResult> {
104
- return this.request(`/api/workflows/${this.workflowId}/resumeAsync?runId=${params.runId}`, {
113
+ return this.request(`/api/workflows/${this.workflowId}/resume-async?runId=${params.runId}`, {
105
114
  method: 'POST',
106
115
  body: {
107
116
  stepId: params.stepId,
@@ -119,61 +128,57 @@ export class Workflow extends BaseResource {
119
128
  */
120
129
  private async *streamProcessor(stream: ReadableStream): AsyncGenerator<WorkflowRunResult, void, unknown> {
121
130
  const reader = stream.getReader();
131
+
132
+ // Track if we've finished reading from the stream
133
+ let doneReading = false;
134
+ // Buffer to accumulate partial chunks
122
135
  let buffer = '';
123
136
 
124
137
  try {
125
- while (true) {
138
+ while (!doneReading) {
139
+ // Read the next chunk from the stream
126
140
  const { done, value } = await reader.read();
141
+ doneReading = done;
142
+
143
+ // Skip processing if we're done and there's no value
144
+ if (done && !value) continue;
145
+
146
+ try {
147
+ // Decode binary data to text
148
+ const decoded = value ? new TextDecoder().decode(value) : '';
149
+
150
+ // Split the combined buffer and new data by record separator
151
+ const chunks = (buffer + decoded).split(RECORD_SEPARATOR);
127
152
 
128
- if (done) {
129
- // Process any remaining data in buffer before finishing
130
- if (buffer.trim().length > 0) {
131
- try {
132
- const record = JSON.parse(buffer);
133
- yield record;
134
- } catch (e) {
135
- console.warn('Could not parse final buffer content:', buffer);
153
+ // The last chunk might be incomplete, so save it for the next iteration
154
+ buffer = chunks.pop() || '';
155
+
156
+ // Process complete chunks
157
+ for (const chunk of chunks) {
158
+ if (chunk) {
159
+ // Only process non-empty chunks
160
+ yield JSON.parse(chunk);
136
161
  }
137
162
  }
138
- break;
163
+ } catch (error) {
164
+ // Silently ignore parsing errors to maintain stream processing
165
+ // This allows the stream to continue even if one record is malformed
139
166
  }
167
+ }
140
168
 
141
- // Decode and add to buffer
142
- buffer += new TextDecoder().decode(value);
143
-
144
- // Split the buffer into records
145
- const records = buffer.split('\x1E');
146
-
147
- // Keep the last (potentially incomplete) chunk in the buffer
148
- buffer = records.pop() || '';
149
-
150
- // Process each complete record
151
- for (const record of records) {
152
- if (record.trim().length > 0) {
153
- try {
154
- // Assuming the records are JSON strings
155
- const parsedRecord = JSON.parse(record);
156
-
157
- //Check to see if all steps are completed and cancel reader
158
- const isWorkflowCompleted = Object.values(parsedRecord?.activePaths || {}).every(
159
- (path: any) =>
160
- path.status === 'completed' ||
161
- path.status === 'suspended' ||
162
- path.status === 'failed' ||
163
- path.status === 'skipped',
164
- );
165
- if (isWorkflowCompleted) {
166
- reader.cancel();
167
- }
168
- yield parsedRecord;
169
- } catch (e) {
170
- throw new Error(`Could not parse record: ${record}, ${e}`);
171
- }
172
- }
169
+ // Process any remaining data in the buffer after stream is done
170
+ if (buffer) {
171
+ try {
172
+ yield JSON.parse(buffer);
173
+ } catch {
174
+ // Ignore parsing error for final chunk
173
175
  }
174
176
  }
175
177
  } finally {
176
- reader.cancel();
178
+ // Always ensure we clean up the reader
179
+ reader.cancel().catch(() => {
180
+ // Ignore cancel errors
181
+ });
177
182
  }
178
183
  }
179
184
 
package/src/types.ts CHANGED
@@ -69,6 +69,7 @@ export interface GetWorkflowResponse {
69
69
  steps: Record<string, StepAction<any, any, any, any>>;
70
70
  stepGraph: StepGraph;
71
71
  stepSubscriberGraph: Record<string, StepGraph>;
72
+ workflowId?: string;
72
73
  }
73
74
 
74
75
  export type WorkflowRunResult = {