@mastra/hono 1.4.19-alpha.4 → 1.4.19-alpha.8

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/CHANGELOG.md CHANGED
@@ -1,5 +1,58 @@
1
1
  # @mastra/hono
2
2
 
3
+ ## 1.4.19-alpha.8
4
+
5
+ ### Patch Changes
6
+
7
+ - Improved agent thread subscription resilience by keeping server streams active during idle periods and allowing the JavaScript client to reconnect when subscription streams close or resubscribe requests fail. ([#17045](https://github.com/mastra-ai/mastra/pull/17045))
8
+
9
+ Enable automatic reconnection with `subscription.processDataStream({ onChunk: chunk => console.log(chunk), reconnect: true })`.
10
+
11
+ - Fixed SSE streams so browser clients can connect to long-lived subscriptions before the first stream event is available. ([#16540](https://github.com/mastra-ai/mastra/pull/16540))
12
+
13
+ - Updated dependencies [[`c35b962`](https://github.com/mastra-ai/mastra/commit/c35b9625c7e854fcfdeee226a3338a750d0ff211), [`c35b962`](https://github.com/mastra-ai/mastra/commit/c35b9625c7e854fcfdeee226a3338a750d0ff211), [`4084113`](https://github.com/mastra-ai/mastra/commit/408411370fc48a822e8b616b3b63f9409774e0e9), [`bc01b1b`](https://github.com/mastra-ai/mastra/commit/bc01b1bfafe381d90af909f8bce7eeb4eee779f2)]:
14
+ - @mastra/core@1.37.0-alpha.8
15
+ - @mastra/server@1.37.0-alpha.8
16
+
17
+ ## 1.4.19-alpha.7
18
+
19
+ ### Patch Changes
20
+
21
+ - Updated dependencies [[`168fa09`](https://github.com/mastra-ai/mastra/commit/168fa09d6b39114cb8c13bd06f1dccb9bc81c6cd)]:
22
+ - @mastra/core@1.37.0-alpha.7
23
+ - @mastra/server@1.37.0-alpha.7
24
+
25
+ ## 1.4.19-alpha.6
26
+
27
+ ### Patch Changes
28
+
29
+ - Developers can now cancel long-running custom API route work when clients disconnect. Node-based adapters pass abort signals into custom route handlers, clean up response streams correctly, and still surface upstream response body errors. ([#16335](https://github.com/mastra-ai/mastra/pull/16335))
30
+
31
+ ```ts
32
+ registerApiRoute('/stream', {
33
+ method: 'GET',
34
+ handler: async c => {
35
+ const stream = await agent.stream(prompt, {
36
+ abortSignal: c.req.raw.signal,
37
+ });
38
+
39
+ return stream.toTextStreamResponse();
40
+ },
41
+ });
42
+ ```
43
+
44
+ - Updated dependencies [[`fafed7a`](https://github.com/mastra-ai/mastra/commit/fafed7a24dc320f7c92ee872c347f4be087fd689), [`0cbece9`](https://github.com/mastra-ai/mastra/commit/0cbece9d832cb134a74cdbf3682d390a058215a4), [`7dfe1bc`](https://github.com/mastra-ai/mastra/commit/7dfe1bcfe71d261a6fd6bbf29b1dec49d78fb98f), [`70cb714`](https://github.com/mastra-ai/mastra/commit/70cb7149c8f16f478e15b58498254a53181750a4), [`7f9da22`](https://github.com/mastra-ai/mastra/commit/7f9da22efd5aa595e138a31de55a5f0f2f28b33d)]:
45
+ - @mastra/server@1.37.0-alpha.6
46
+ - @mastra/core@1.37.0-alpha.6
47
+
48
+ ## 1.4.19-alpha.5
49
+
50
+ ### Patch Changes
51
+
52
+ - Updated dependencies [[`6096445`](https://github.com/mastra-ai/mastra/commit/60964459733f0ab384584d95e19c36607ffdf7b0), [`91cf0e0`](https://github.com/mastra-ai/mastra/commit/91cf0e027e511b871481a8576b56b7af83b15afd)]:
53
+ - @mastra/core@1.37.0-alpha.5
54
+ - @mastra/server@1.37.0-alpha.5
55
+
3
56
  ## 1.4.19-alpha.4
4
57
 
5
58
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -9,6 +9,9 @@ var auth = require('@mastra/server/auth');
9
9
  var browserStream = require('@mastra/server/browser-stream');
10
10
 
11
11
  // src/index.ts
12
+
13
+ // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/core.js
14
+ var _a;
12
15
  // @__NO_SIDE_EFFECTS__
13
16
  function $constructor(name, initializer3, params) {
14
17
  function init(inst, def) {
@@ -61,15 +64,16 @@ function $constructor(name, initializer3, params) {
61
64
  Object.defineProperty(_, "name", { value: name });
62
65
  return _;
63
66
  }
67
+ (_a = globalThis).__zod_globalConfig ?? (_a.__zod_globalConfig = {});
64
68
 
65
- // ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/util.js
69
+ // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/util.js
66
70
  function jsonStringifyReplacer(_, value) {
67
71
  if (typeof value === "bigint")
68
72
  return value.toString();
69
73
  return value;
70
74
  }
71
75
 
72
- // ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/errors.js
76
+ // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/errors.js
73
77
  var initializer = (inst, def) => {
74
78
  inst.name = "$ZodError";
75
79
  Object.defineProperty(inst, "_zod", {
@@ -87,7 +91,7 @@ var initializer = (inst, def) => {
87
91
  });
88
92
  };
89
93
  var $ZodError = $constructor("$ZodError", initializer);
90
- function flattenError(error, mapper = (issue2) => issue2.message) {
94
+ function flattenError(error, mapper = (issue) => issue.message) {
91
95
  const fieldErrors = {};
92
96
  const formErrors = [];
93
97
  for (const sub of error.issues) {
@@ -100,32 +104,35 @@ function flattenError(error, mapper = (issue2) => issue2.message) {
100
104
  }
101
105
  return { formErrors, fieldErrors };
102
106
  }
103
- function formatError(error, mapper = (issue2) => issue2.message) {
107
+ function formatError(error, mapper = (issue) => issue.message) {
104
108
  const fieldErrors = { _errors: [] };
105
- const processError = (error2) => {
106
- for (const issue2 of error2.issues) {
107
- if (issue2.code === "invalid_union" && issue2.errors.length) {
108
- issue2.errors.map((issues) => processError({ issues }));
109
- } else if (issue2.code === "invalid_key") {
110
- processError({ issues: issue2.issues });
111
- } else if (issue2.code === "invalid_element") {
112
- processError({ issues: issue2.issues });
113
- } else if (issue2.path.length === 0) {
114
- fieldErrors._errors.push(mapper(issue2));
109
+ const processError = (error2, path = []) => {
110
+ for (const issue of error2.issues) {
111
+ if (issue.code === "invalid_union" && issue.errors.length) {
112
+ issue.errors.map((issues) => processError({ issues }, [...path, ...issue.path]));
113
+ } else if (issue.code === "invalid_key") {
114
+ processError({ issues: issue.issues }, [...path, ...issue.path]);
115
+ } else if (issue.code === "invalid_element") {
116
+ processError({ issues: issue.issues }, [...path, ...issue.path]);
115
117
  } else {
116
- let curr = fieldErrors;
117
- let i = 0;
118
- while (i < issue2.path.length) {
119
- const el = issue2.path[i];
120
- const terminal = i === issue2.path.length - 1;
121
- if (!terminal) {
122
- curr[el] = curr[el] || { _errors: [] };
123
- } else {
124
- curr[el] = curr[el] || { _errors: [] };
125
- curr[el]._errors.push(mapper(issue2));
118
+ const fullpath = [...path, ...issue.path];
119
+ if (fullpath.length === 0) {
120
+ fieldErrors._errors.push(mapper(issue));
121
+ } else {
122
+ let curr = fieldErrors;
123
+ let i = 0;
124
+ while (i < fullpath.length) {
125
+ const el = fullpath[i];
126
+ const terminal = i === fullpath.length - 1;
127
+ if (!terminal) {
128
+ curr[el] = curr[el] || { _errors: [] };
129
+ } else {
130
+ curr[el] = curr[el] || { _errors: [] };
131
+ curr[el]._errors.push(mapper(issue));
132
+ }
133
+ curr = curr[el];
134
+ i++;
126
135
  }
127
- curr = curr[el];
128
- i++;
129
136
  }
130
137
  }
131
138
  }
@@ -134,54 +141,7 @@ function formatError(error, mapper = (issue2) => issue2.message) {
134
141
  return fieldErrors;
135
142
  }
136
143
 
137
- // ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/registries.js
138
- var _a;
139
- var $ZodRegistry = class {
140
- constructor() {
141
- this._map = /* @__PURE__ */ new WeakMap();
142
- this._idmap = /* @__PURE__ */ new Map();
143
- }
144
- add(schema, ..._meta) {
145
- const meta = _meta[0];
146
- this._map.set(schema, meta);
147
- if (meta && typeof meta === "object" && "id" in meta) {
148
- this._idmap.set(meta.id, schema);
149
- }
150
- return this;
151
- }
152
- clear() {
153
- this._map = /* @__PURE__ */ new WeakMap();
154
- this._idmap = /* @__PURE__ */ new Map();
155
- return this;
156
- }
157
- remove(schema) {
158
- const meta = this._map.get(schema);
159
- if (meta && typeof meta === "object" && "id" in meta) {
160
- this._idmap.delete(meta.id);
161
- }
162
- this._map.delete(schema);
163
- return this;
164
- }
165
- get(schema) {
166
- const p = schema._zod.parent;
167
- if (p) {
168
- const pm = { ...this.get(p) ?? {} };
169
- delete pm.id;
170
- const f = { ...pm, ...this._map.get(schema) };
171
- return Object.keys(f).length ? f : void 0;
172
- }
173
- return this._map.get(schema);
174
- }
175
- has(schema) {
176
- return this._map.has(schema);
177
- }
178
- };
179
- function registry() {
180
- return new $ZodRegistry();
181
- }
182
- (_a = globalThis).__zod_globalRegistry ?? (_a.__zod_globalRegistry = registry());
183
-
184
- // ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/errors.js
144
+ // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/errors.js
185
145
  var initializer2 = (inst, issues) => {
186
146
  $ZodError.init(inst, issues);
187
147
  inst.name = "ZodError";
@@ -195,8 +155,8 @@ var initializer2 = (inst, issues) => {
195
155
  // enumerable: false,
196
156
  },
197
157
  addIssue: {
198
- value: (issue2) => {
199
- inst.issues.push(issue2);
158
+ value: (issue) => {
159
+ inst.issues.push(issue);
200
160
  inst.message = JSON.stringify(inst.issues, jsonStringifyReplacer, 2);
201
161
  }
202
162
  // enumerable: false,
@@ -216,7 +176,7 @@ var initializer2 = (inst, issues) => {
216
176
  }
217
177
  });
218
178
  };
219
- var ZodError = $constructor("ZodError", initializer2);
179
+ var ZodError = /* @__PURE__ */ $constructor("ZodError", initializer2);
220
180
  function createAuthMiddleware({ mastra, requiresAuth = true }) {
221
181
  return async (c, next) => {
222
182
  if (!requiresAuth) {
@@ -256,7 +216,7 @@ function createAuthMiddleware({ mastra, requiresAuth = true }) {
256
216
  return c.json(result.body, result.status);
257
217
  };
258
218
  }
259
- async function setupBrowserStream(app, config2) {
219
+ async function setupBrowserStream(app, config) {
260
220
  let createNodeWebSocket;
261
221
  try {
262
222
  const mod = "@hono/node-ws";
@@ -270,8 +230,8 @@ async function setupBrowserStream(app, config2) {
270
230
  return null;
271
231
  }
272
232
  const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app });
273
- const registry2 = new browserStream.ViewerRegistry();
274
- const rawPrefix = config2.apiPrefix ?? "/api";
233
+ const registry = new browserStream.ViewerRegistry();
234
+ const rawPrefix = config.apiPrefix ?? "/api";
275
235
  const trimmed = rawPrefix.endsWith("/") ? rawPrefix.slice(0, -1) : rawPrefix;
276
236
  const apiPrefix = trimmed || "/api";
277
237
  app.get(
@@ -283,20 +243,20 @@ async function setupBrowserStream(app, config2) {
283
243
  return {
284
244
  onOpen(_event, ws) {
285
245
  ws.send(JSON.stringify({ status: "connected" }));
286
- void registry2.addViewer(viewerKey, ws, config2.getToolset, agentId, threadId);
246
+ void registry.addViewer(viewerKey, ws, config.getToolset, agentId, threadId);
287
247
  },
288
248
  onMessage(event, _ws) {
289
249
  const data = typeof event.data === "string" ? event.data : null;
290
250
  if (data) {
291
- void browserStream.handleInputMessage(data, config2.getToolset, agentId, threadId);
251
+ void browserStream.handleInputMessage(data, config.getToolset, agentId, threadId);
292
252
  }
293
253
  },
294
254
  onClose(_event, ws) {
295
- void registry2.removeViewer(viewerKey, ws);
255
+ void registry.removeViewer(viewerKey, ws);
296
256
  },
297
257
  onError(event, ws) {
298
258
  console.error("[BrowserStream] WebSocket error:", event);
299
- void registry2.removeViewer(viewerKey, ws);
259
+ void registry.removeViewer(viewerKey, ws);
300
260
  }
301
261
  };
302
262
  })
@@ -307,7 +267,7 @@ async function setupBrowserStream(app, config2) {
307
267
  return c.json({ error: "Agent ID is required" }, 400);
308
268
  }
309
269
  const threadId = c.req.query("threadId");
310
- const toolset = await config2.getToolset(agentId);
270
+ const toolset = await config.getToolset(agentId);
311
271
  if (!toolset) {
312
272
  return c.json({ hasSession: false, screencastAvailable: true });
313
273
  }
@@ -319,7 +279,7 @@ async function setupBrowserStream(app, config2) {
319
279
  if (!agentId) {
320
280
  return c.json({ error: "Agent ID is required" }, 400);
321
281
  }
322
- const toolset = await config2.getToolset(agentId);
282
+ const toolset = await config.getToolset(agentId);
323
283
  if (!toolset) {
324
284
  return c.json({ error: "No browser session for this agent" }, 404);
325
285
  }
@@ -333,12 +293,12 @@ async function setupBrowserStream(app, config2) {
333
293
  const scope = toolset.getScope();
334
294
  const viewerKey = threadId ? `${agentId}:${threadId}` : agentId;
335
295
  if (scope === "thread" && threadId) {
336
- await registry2.closeBrowserSession(viewerKey);
296
+ await registry.closeBrowserSession(viewerKey);
337
297
  if ("closeThreadSession" in toolset && typeof toolset.closeThreadSession === "function") {
338
298
  await toolset.closeThreadSession(threadId);
339
299
  }
340
300
  } else {
341
- await registry2.closeBrowserSession(viewerKey);
301
+ await registry.closeBrowserSession(viewerKey);
342
302
  await toolset.close();
343
303
  }
344
304
  return c.json({ success: true });
@@ -347,7 +307,7 @@ async function setupBrowserStream(app, config2) {
347
307
  return c.json({ error: "Failed to close browser" }, 500);
348
308
  }
349
309
  });
350
- return { injectWebSocket, registry: registry2 };
310
+ return { injectWebSocket, registry };
351
311
  }
352
312
 
353
313
  // src/index.ts
@@ -437,6 +397,9 @@ var MastraServer = class extends serverAdapter.MastraServer {
437
397
  return streaming.stream(
438
398
  res,
439
399
  async (stream2) => {
400
+ if (streamFormat === "sse") {
401
+ await stream2.write(": connected\n\n");
402
+ }
440
403
  const readableStream = result instanceof ReadableStream ? result : result.fullStream;
441
404
  const reader = readableStream.getReader();
442
405
  stream2.onAbort(() => {
@@ -447,6 +410,10 @@ var MastraServer = class extends serverAdapter.MastraServer {
447
410
  const { done, value } = await reader.read();
448
411
  if (done) break;
449
412
  if (value) {
413
+ if (streamFormat === "sse" && typeof value === "string" && value.startsWith(":")) {
414
+ await stream2.write(value);
415
+ continue;
416
+ }
450
417
  const shouldRedact = this.streamOptions?.redact ?? true;
451
418
  const outputValue = shouldRedact ? serverAdapter.redactStreamChunk(value) : value;
452
419
  if (streamFormat === "sse") {
@@ -864,7 +831,8 @@ var MastraServer = class extends serverAdapter.MastraServer {
864
831
  c.req.method,
865
832
  reqHeaders,
866
833
  c.req.raw.body,
867
- c.get("requestContext")
834
+ c.get("requestContext"),
835
+ c.req.raw.signal
868
836
  );
869
837
  if (!response) {
870
838
  return c.json({ error: "Not Found" }, 404);
@@ -892,14 +860,14 @@ var MastraServer = class extends serverAdapter.MastraServer {
892
860
  const method = c.req.method;
893
861
  const path = c.req.path;
894
862
  await next();
895
- const duration2 = Date.now() - start;
863
+ const duration = Date.now() - start;
896
864
  const status = c.res.status;
897
865
  const level = this.httpLoggingConfig?.level || "info";
898
866
  const logData = {
899
867
  method,
900
868
  path,
901
869
  status,
902
- duration: `${duration2}ms`
870
+ duration: `${duration}ms`
903
871
  };
904
872
  if (this.httpLoggingConfig?.includeQueryParams) {
905
873
  logData.query = c.req.query();
@@ -915,7 +883,7 @@ var MastraServer = class extends serverAdapter.MastraServer {
915
883
  });
916
884
  logData.headers = headers;
917
885
  }
918
- this.logger[level](`${method} ${path} ${status} ${duration2}ms`, logData);
886
+ this.logger[level](`${method} ${path} ${status} ${duration}ms`, logData);
919
887
  });
920
888
  }
921
889
  };