@mastra/connect 1.1.0-alpha.1 → 1.1.0-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.
package/dist/index.cjs CHANGED
@@ -7888,10 +7888,15 @@ const SentenceSchema = zod.z.object({
7888
7888
  speaker_name: zod.z.string().nullish(),
7889
7889
  speaker_id: zod.z.string().nullish(),
7890
7890
  raw_text: zod.z.string().nullish(),
7891
- start_time: zod.z.string().nullish(),
7892
- end_time: zod.z.string().nullish(),
7891
+ start_time: zod.z.number().nullish(),
7892
+ end_time: zod.z.number().nullish(),
7893
7893
  text: zod.z.string().nullish()
7894
7894
  });
7895
+ const ProviderSentenceSchema = SentenceSchema.extend({
7896
+ speaker_id: zod.z.union([zod.z.string(), zod.z.number()]).nullish(),
7897
+ start_time: zod.z.union([zod.z.number(), zod.z.string()]).nullish(),
7898
+ end_time: zod.z.union([zod.z.number(), zod.z.string()]).nullish()
7899
+ });
7895
7900
  const SummarySectionSchema = zod.z.object({
7896
7901
  title: zod.z.string().nullish(),
7897
7902
  content: zod.z.string().nullish()
@@ -7958,7 +7963,7 @@ const AnalyticsSchema = zod.z.object({
7958
7963
  const TranscriptSchema = zod.z.object({
7959
7964
  id: zod.z.string().nullish(),
7960
7965
  title: zod.z.string().nullish(),
7961
- sentences: zod.z.array(SentenceSchema).nullish(),
7966
+ sentences: zod.z.array(ProviderSentenceSchema).nullish(),
7962
7967
  summary: ProviderSummarySchema$1.nullable().optional(),
7963
7968
  speakers: zod.z.array(SpeakerSchema).nullish(),
7964
7969
  meeting_info: MeetingInfoSchema.nullable().optional(),
@@ -7986,6 +7991,22 @@ const getTranscriptOutputSchema = zod.z.object({
7986
7991
  function normalizeActionItems$1(actionItems) {
7987
7992
  return Array.isArray(actionItems) ? actionItems.join("\n") : actionItems;
7988
7993
  }
7994
+ function toFiniteNumber(value) {
7995
+ if (value == null) return void 0;
7996
+ if (typeof value === "number") return Number.isFinite(value) ? value : void 0;
7997
+ const trimmed = value.trim();
7998
+ if (trimmed === "") return void 0;
7999
+ const parsed = Number(trimmed);
8000
+ return Number.isFinite(parsed) ? parsed : void 0;
8001
+ }
8002
+ function normalizeSentence(sentence) {
8003
+ return {
8004
+ ...sentence,
8005
+ speaker_id: sentence.speaker_id != null ? String(sentence.speaker_id) : sentence.speaker_id,
8006
+ start_time: toFiniteNumber(sentence.start_time),
8007
+ end_time: toFiniteNumber(sentence.end_time)
8008
+ };
8009
+ }
7989
8010
  function getTranscriptTool(proxy) {
7990
8011
  return (0, _mastra_core_tools.createTool)({
7991
8012
  id: "fireflies_get_transcript",
@@ -8091,7 +8112,7 @@ function getTranscriptTool(proxy) {
8091
8112
  return {
8092
8113
  id: transcript.id ?? void 0,
8093
8114
  title: transcript.title ?? void 0,
8094
- sentences: transcript.sentences ?? void 0,
8115
+ sentences: transcript.sentences ? transcript.sentences.map(normalizeSentence) : void 0,
8095
8116
  summary: transcript.summary ? {
8096
8117
  ...transcript.summary,
8097
8118
  action_items: transcript.summary.action_items != null ? normalizeActionItems$1(transcript.summary.action_items) : transcript.summary.action_items
@@ -19820,11 +19841,11 @@ function insertTextTool(proxy) {
19820
19841
  }
19821
19842
  //#endregion
19822
19843
  //#region src/providers/google-docs/tools/list-revisions.ts
19823
- const listRevisionsInputSchema = zod.z.object({
19844
+ const listRevisionsInputSchema$1 = zod.z.object({
19824
19845
  documentId: zod.z.string().describe("Google Docs document ID. Example: \"1Kj3d86Z-Sfd56YP4dImQ-ggMRyP2QZ_BRO33zOO224c\""),
19825
19846
  pageToken: zod.z.string().optional().describe("Pagination token from the previous response. Omit for the first page.")
19826
19847
  });
19827
- const LastModifyingUserSchema = zod.z.object({
19848
+ const LastModifyingUserSchema$1 = zod.z.object({
19828
19849
  kind: zod.z.string().optional(),
19829
19850
  displayName: zod.z.string().optional(),
19830
19851
  photoLink: zod.z.string().optional(),
@@ -19832,27 +19853,27 @@ const LastModifyingUserSchema = zod.z.object({
19832
19853
  permissionId: zod.z.string().optional(),
19833
19854
  emailAddress: zod.z.string().optional()
19834
19855
  });
19835
- const RevisionSchema = zod.z.object({
19856
+ const RevisionSchema$1 = zod.z.object({
19836
19857
  id: zod.z.string(),
19837
19858
  modifiedTime: zod.z.string().optional(),
19838
- lastModifyingUser: LastModifyingUserSchema.optional(),
19859
+ lastModifyingUser: LastModifyingUserSchema$1.optional(),
19839
19860
  keepForever: zod.z.boolean().optional(),
19840
19861
  published: zod.z.boolean().optional()
19841
19862
  });
19842
- const listRevisionsOutputSchema = zod.z.object({
19843
- revisions: zod.z.array(RevisionSchema),
19863
+ const listRevisionsOutputSchema$1 = zod.z.object({
19864
+ revisions: zod.z.array(RevisionSchema$1),
19844
19865
  nextPageToken: zod.z.string().optional()
19845
19866
  });
19846
- const DriveRevisionsResponseSchema = zod.z.object({
19867
+ const DriveRevisionsResponseSchema$1 = zod.z.object({
19847
19868
  nextPageToken: zod.z.string().optional(),
19848
19869
  revisions: zod.z.array(zod.z.unknown()).optional()
19849
19870
  });
19850
- function listRevisionsTool(proxy) {
19871
+ function listRevisionsTool$1(proxy) {
19851
19872
  return (0, _mastra_core_tools.createTool)({
19852
19873
  id: "google_docs_list_revisions",
19853
19874
  description: "List the revision history for a Google Doc.",
19854
- inputSchema: listRevisionsInputSchema,
19855
- outputSchema: listRevisionsOutputSchema,
19875
+ inputSchema: listRevisionsInputSchema$1,
19876
+ outputSchema: listRevisionsOutputSchema$1,
19856
19877
  execute: async (input, { requestContext }) => {
19857
19878
  const platformProxy = proxy.withRequestContext(requestContext);
19858
19879
  const response = await platformProxy.get({
@@ -19865,7 +19886,7 @@ function listRevisionsTool(proxy) {
19865
19886
  baseUrlOverride: "https://www.googleapis.com",
19866
19887
  retries: 3
19867
19888
  });
19868
- const parsedResponse = DriveRevisionsResponseSchema.safeParse(response.data);
19889
+ const parsedResponse = DriveRevisionsResponseSchema$1.safeParse(response.data);
19869
19890
  if (!parsedResponse.success) throw new platformProxy.ActionError({
19870
19891
  type: "invalid_response",
19871
19892
  message: "Invalid response from Google Drive API"
@@ -19873,7 +19894,7 @@ function listRevisionsTool(proxy) {
19873
19894
  const rawRevisions = parsedResponse.data.revisions ?? [];
19874
19895
  const revisions = [];
19875
19896
  for (const rawRevision of rawRevisions) {
19876
- const parsedRevision = RevisionSchema.safeParse(rawRevision);
19897
+ const parsedRevision = RevisionSchema$1.safeParse(rawRevision);
19877
19898
  if (parsedRevision.success) revisions.push(parsedRevision.data);
19878
19899
  }
19879
19900
  return {
@@ -20769,7 +20790,7 @@ function createGoogleDocsTools(options) {
20769
20790
  google_docs_insert_table_row: insertTableRowTool$1(platformProxy),
20770
20791
  google_docs_insert_table: insertTableTool(platformProxy),
20771
20792
  google_docs_insert_text: insertTextTool(platformProxy),
20772
- google_docs_list_revisions: listRevisionsTool(platformProxy),
20793
+ google_docs_list_revisions: listRevisionsTool$1(platformProxy),
20773
20794
  google_docs_merge_table_cells: mergeTableCellsTool(platformProxy),
20774
20795
  google_docs_pin_table_header_rows: pinTableHeaderRowsTool(platformProxy),
20775
20796
  google_docs_replace_all_text: replaceAllTextTool(platformProxy),
@@ -20923,7 +20944,10 @@ function createFolderTool(proxy) {
20923
20944
  if (input.parentId) requestBody["parents"] = [input.parentId];
20924
20945
  const response = await platformProxy.post({
20925
20946
  endpoint: "/drive/v3/files",
20926
- params: { fields: "id,name,mimeType,createdTime,parents" },
20947
+ params: {
20948
+ supportsAllDrives: "true",
20949
+ fields: "id,name,mimeType,createdTime,parents"
20950
+ },
20927
20951
  data: requestBody,
20928
20952
  retries: 3
20929
20953
  });
@@ -21122,6 +21146,56 @@ function emptyTrashTool(proxy) {
21122
21146
  });
21123
21147
  }
21124
21148
  //#endregion
21149
+ //#region src/providers/google-drive/tools/export-file.ts
21150
+ const exportFileInputSchema = zod.z.object({
21151
+ fileId: zod.z.string().describe("The ID of the Google Workspace file to export (Doc, Sheet, Slide, etc.). Example: \"1Kj3d86Z-Sfd56YP4dImQ-ggMRyP2QZ_BRO33zOO224c\""),
21152
+ mimeType: zod.z.enum([
21153
+ "application/pdf",
21154
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
21155
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
21156
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
21157
+ "text/html",
21158
+ "text/plain",
21159
+ "text/csv",
21160
+ "application/rtf",
21161
+ "application/epub+zip"
21162
+ ]).describe("The target MIME type for the export.")
21163
+ });
21164
+ const exportFileOutputSchema = zod.z.object({
21165
+ fileId: zod.z.string(),
21166
+ mimeType: zod.z.string(),
21167
+ data: zod.z.string().describe("The exported file encoded as a base64 string."),
21168
+ size: zod.z.number().describe("The size of the exported data in bytes.")
21169
+ });
21170
+ function exportFileTool(proxy) {
21171
+ return (0, _mastra_core_tools.createTool)({
21172
+ id: "google_drive_export_file",
21173
+ description: "Export a Google Workspace file (Doc, Sheet, Slide, etc.) to the specified MIME type.",
21174
+ inputSchema: exportFileInputSchema,
21175
+ outputSchema: exportFileOutputSchema,
21176
+ execute: async (input, { requestContext }) => {
21177
+ const platformProxy = proxy.withRequestContext(requestContext);
21178
+ const rawData = (await platformProxy.get({
21179
+ endpoint: `/drive/v3/files/${encodeURIComponent(input.fileId)}/export`,
21180
+ params: { mimeType: input.mimeType },
21181
+ responseType: "arraybuffer",
21182
+ retries: 3
21183
+ })).data;
21184
+ if (typeof rawData !== "object" || rawData === null) throw new platformProxy.ActionError({
21185
+ type: "invalid_response",
21186
+ message: "Expected binary response from export API."
21187
+ });
21188
+ const buffer = Buffer.isBuffer(rawData) ? rawData : Buffer.from(rawData);
21189
+ return {
21190
+ fileId: input.fileId,
21191
+ mimeType: input.mimeType,
21192
+ data: buffer.toString("base64"),
21193
+ size: buffer.length
21194
+ };
21195
+ }
21196
+ });
21197
+ }
21198
+ //#endregion
21125
21199
  //#region src/providers/google-drive/tools/find-file.ts
21126
21200
  const findFileInputSchema = zod.z.object({
21127
21201
  query: zod.z.string().optional().describe("Search query string. Uses Google Drive search query syntax. Example: \"name contains 'report'\" or \"mimeType = 'application/pdf'\". If not provided, returns all files."),
@@ -21947,6 +22021,70 @@ function listPermissionsTool(proxy) {
21947
22021
  });
21948
22022
  }
21949
22023
  //#endregion
22024
+ //#region src/providers/google-drive/tools/list-revisions.ts
22025
+ const listRevisionsInputSchema = zod.z.object({
22026
+ fileId: zod.z.string().describe("The Drive file ID. Example: \"1Kj3d86Z-Sfd56YP4dImQ-ggMRyP2QZ_BRO33zOO224c\""),
22027
+ pageToken: zod.z.string().optional().describe("Pagination token from the previous response. Omit for the first page.")
22028
+ });
22029
+ const LastModifyingUserSchema = zod.z.object({
22030
+ kind: zod.z.string().optional(),
22031
+ displayName: zod.z.string().optional(),
22032
+ photoLink: zod.z.string().optional(),
22033
+ me: zod.z.boolean().optional(),
22034
+ permissionId: zod.z.string().optional(),
22035
+ emailAddress: zod.z.string().optional()
22036
+ });
22037
+ const RevisionSchema = zod.z.object({
22038
+ id: zod.z.string(),
22039
+ modifiedTime: zod.z.string().optional(),
22040
+ lastModifyingUser: LastModifyingUserSchema.optional(),
22041
+ keepForever: zod.z.boolean().optional(),
22042
+ published: zod.z.boolean().optional()
22043
+ });
22044
+ const listRevisionsOutputSchema = zod.z.object({
22045
+ revisions: zod.z.array(RevisionSchema),
22046
+ nextPageToken: zod.z.string().optional()
22047
+ });
22048
+ const DriveRevisionsResponseSchema = zod.z.object({
22049
+ nextPageToken: zod.z.string().optional(),
22050
+ revisions: zod.z.array(zod.z.unknown()).optional()
22051
+ });
22052
+ function listRevisionsTool(proxy) {
22053
+ return (0, _mastra_core_tools.createTool)({
22054
+ id: "google_drive_list_revisions",
22055
+ description: "List the revision history for a Drive file.",
22056
+ inputSchema: listRevisionsInputSchema,
22057
+ outputSchema: listRevisionsOutputSchema,
22058
+ execute: async (input, { requestContext }) => {
22059
+ const platformProxy = proxy.withRequestContext(requestContext);
22060
+ const response = await platformProxy.get({
22061
+ endpoint: `/drive/v3/files/${encodeURIComponent(input.fileId)}/revisions`,
22062
+ params: {
22063
+ fields: "nextPageToken,revisions(id,modifiedTime,lastModifyingUser,keepForever,published)",
22064
+ pageSize: "100",
22065
+ ...input.pageToken !== void 0 && { pageToken: input.pageToken }
22066
+ },
22067
+ retries: 3
22068
+ });
22069
+ const parsedResponse = DriveRevisionsResponseSchema.safeParse(response.data);
22070
+ if (!parsedResponse.success) throw new platformProxy.ActionError({
22071
+ type: "invalid_response",
22072
+ message: "Invalid response from Google Drive API"
22073
+ });
22074
+ const rawRevisions = parsedResponse.data.revisions ?? [];
22075
+ const revisions = [];
22076
+ for (const rawRevision of rawRevisions) {
22077
+ const parsedRevision = RevisionSchema.safeParse(rawRevision);
22078
+ if (parsedRevision.success) revisions.push(parsedRevision.data);
22079
+ }
22080
+ return {
22081
+ revisions,
22082
+ ...parsedResponse.data.nextPageToken !== void 0 && { nextPageToken: parsedResponse.data.nextPageToken }
22083
+ };
22084
+ }
22085
+ });
22086
+ }
22087
+ //#endregion
21950
22088
  //#region src/providers/google-drive/tools/move-file.ts
21951
22089
  const moveFileInputSchema = zod.z.object({
21952
22090
  fileId: zod.z.string().describe("The ID of the file to move. Example: \"1mD3ukEAmRqo8u0RF_Cr6IJl9f_uWTYH03vesDhB5Svw\""),
@@ -21972,6 +22110,7 @@ function moveFileTool(proxy) {
21972
22110
  params: {
21973
22111
  addParents: input.toFolderId,
21974
22112
  removeParents: input.fromFolderId,
22113
+ supportsAllDrives: "true",
21975
22114
  fields: "id,name,mimeType,parents"
21976
22115
  },
21977
22116
  retries: 3
@@ -22321,7 +22460,10 @@ function uploadDocumentTool(proxy) {
22321
22460
  if (input.folderId) metadataBody["parents"] = [input.folderId];
22322
22461
  const createResponse = await platformProxy.post({
22323
22462
  endpoint: "/drive/v3/files",
22324
- params: { fields: "id,name,mimeType,webViewLink,webContentLink" },
22463
+ params: {
22464
+ supportsAllDrives: "true",
22465
+ fields: "id,name,mimeType,webViewLink,webContentLink"
22466
+ },
22325
22467
  data: metadataBody,
22326
22468
  retries: 3
22327
22469
  });
@@ -22336,6 +22478,7 @@ function uploadDocumentTool(proxy) {
22336
22478
  endpoint: `/upload/drive/v3/files/${fileId}`,
22337
22479
  params: {
22338
22480
  uploadType: "media",
22481
+ supportsAllDrives: "true",
22339
22482
  fields: "id,name,mimeType,webViewLink,webContentLink"
22340
22483
  },
22341
22484
  headers: { "Content-Type": input.mimeType },
@@ -22346,6 +22489,7 @@ function uploadDocumentTool(proxy) {
22346
22489
  const status = error?.response?.status;
22347
22490
  if (typeof status === "number" && status >= 400 && status < 500) await platformProxy.delete({
22348
22491
  endpoint: `/drive/v3/files/${fileId}`,
22492
+ params: { supportsAllDrives: "true" },
22349
22493
  retries: 3
22350
22494
  }).catch(() => void 0);
22351
22495
  throw error;
@@ -22382,6 +22526,7 @@ function createGoogleDriveTools(options) {
22382
22526
  google_drive_delete_permission: deletePermissionTool(platformProxy),
22383
22527
  google_drive_delete_shared_drive: deleteSharedDriveTool(platformProxy),
22384
22528
  google_drive_empty_trash: emptyTrashTool(platformProxy),
22529
+ google_drive_export_file: exportFileTool(platformProxy),
22385
22530
  google_drive_find_file: findFileTool(platformProxy),
22386
22531
  google_drive_find_folder: findFolderTool(platformProxy),
22387
22532
  google_drive_get_about: getAboutTool(platformProxy),
@@ -22396,6 +22541,7 @@ function createGoogleDriveTools(options) {
22396
22541
  google_drive_list_drives: listDrivesTool(platformProxy),
22397
22542
  google_drive_list_files_non_unified: listFilesNonUnifiedTool(platformProxy),
22398
22543
  google_drive_list_permissions: listPermissionsTool(platformProxy),
22544
+ google_drive_list_revisions: listRevisionsTool(platformProxy),
22399
22545
  google_drive_move_file: moveFileTool(platformProxy),
22400
22546
  google_drive_unhide_shared_drive: unhideSharedDriveTool(platformProxy),
22401
22547
  google_drive_update_comment: updateCommentTool$2(platformProxy),
@@ -75103,8 +75249,14 @@ let nextResolverId = 0;
75103
75249
  * Expected provider absence is silently skipped. Actionable per-integration
75104
75250
  * problems during resolution (needs re-auth or ambiguity) are downgraded to
75105
75251
  * warn-and-skip so one bad integration never takes down the whole toolset.
75252
+ *
75253
+ * Pass a callback instead of an options object to vary options per request
75254
+ * (see {@link ToolsOptionsInput}). With the callback form, configuration
75255
+ * validation runs at the first resolution that produces a given options
75256
+ * value — still failing loudly — instead of at call time.
75106
75257
  */
75107
75258
  function tools(options = {}) {
75259
+ if (typeof options === "function") return dynamicTools(options);
75108
75260
  const projectId = options.projectId?.trim() || process.env.MASTRA_PROJECT_ID?.trim();
75109
75261
  if (!projectId) throw new MastraConnectError("missing_project_id", "Missing project id: set MASTRA_PROJECT_ID or pass projectId.");
75110
75262
  if (options.ttlMs !== void 0 && (!Number.isFinite(options.ttlMs) || options.ttlMs < 0)) throw new MastraConnectError("invalid_options", `Invalid ttlMs (${options.ttlMs}): expected a finite number of milliseconds >= 0.`);
@@ -75212,6 +75364,130 @@ function tools(options = {}) {
75212
75364
  return resolver;
75213
75365
  }
75214
75366
  /**
75367
+ * Most distinct options values a callback-form resolver keeps live caches
75368
+ * (and MCP clients) for at once. Callbacks are expected to produce a small,
75369
+ * closed set of option shapes (one per role, say); the cap exists so a
75370
+ * callback that accidentally derives options from unbounded per-request data
75371
+ * cannot leak an MCP client per request. Eviction is least-recently-used and
75372
+ * disconnects the evicted variant's transports.
75373
+ */
75374
+ const MAX_OPTION_VARIANTS = 32;
75375
+ /**
75376
+ * Builds the callback-form resolver: each resolution invokes `getOptions`
75377
+ * with the request context, then delegates to a memoized static resolver for
75378
+ * that options value, so every distinct options value gets its own snapshot
75379
+ * cache with the normal TTL / stale-while-revalidate semantics. Options
75380
+ * validation happens when a value is first seen (inside `tools()`), so
75381
+ * configuration errors fail that resolution loudly instead of being
75382
+ * swallowed.
75383
+ */
75384
+ function dynamicTools(getOptions) {
75385
+ const variants = /* @__PURE__ */ new Map();
75386
+ let closing;
75387
+ const disconnectEvicted = (entry) => {
75388
+ entry.resolver.disconnect().catch((error) => {
75389
+ console.warn(`[@mastra/connect] Failed to disconnect evicted tools variant: ${error instanceof Error ? error.message : String(error)}`);
75390
+ });
75391
+ };
75392
+ const releaseVariant = (entry) => {
75393
+ entry.inUse -= 1;
75394
+ if (entry.evicted && entry.inUse === 0) disconnectEvicted(entry);
75395
+ };
75396
+ const acquireVariant = async (ctx) => {
75397
+ if (closing) await closing;
75398
+ const options = await getOptions(ctx);
75399
+ if (closing) await closing;
75400
+ if (typeof options !== "object" || options === null || Array.isArray(options)) throw new MastraConnectError("invalid_options", `The tools() options callback must return a ToolsOptions object, got ${options === null ? "null" : Array.isArray(options) ? "an array" : typeof options}.`);
75401
+ const key = hashOptions(options);
75402
+ const existing = variants.get(key);
75403
+ if (existing) {
75404
+ variants.delete(key);
75405
+ variants.set(key, existing);
75406
+ existing.inUse += 1;
75407
+ return existing;
75408
+ }
75409
+ const entry = {
75410
+ resolver: tools(options),
75411
+ inUse: 1,
75412
+ evicted: false
75413
+ };
75414
+ variants.set(key, entry);
75415
+ if (variants.size > MAX_OPTION_VARIANTS) {
75416
+ const [oldestKey, oldest] = variants.entries().next().value;
75417
+ variants.delete(oldestKey);
75418
+ console.warn(`[@mastra/connect] tools() options callback produced more than ${MAX_OPTION_VARIANTS} distinct options values; evicting the least recently used variant. Derive options from a small, closed set of inputs (e.g. roles), not per-request data.`);
75419
+ oldest.evicted = true;
75420
+ if (oldest.inUse === 0) disconnectEvicted(oldest);
75421
+ }
75422
+ return entry;
75423
+ };
75424
+ const resolve = async (ctx) => {
75425
+ const entry = await acquireVariant(ctx);
75426
+ try {
75427
+ return await entry.resolver(ctx);
75428
+ } finally {
75429
+ releaseVariant(entry);
75430
+ }
75431
+ };
75432
+ const resolver = Object.assign(resolve, {
75433
+ refresh: async () => {
75434
+ const entry = await acquireVariant(void 0);
75435
+ try {
75436
+ return await entry.resolver.refresh();
75437
+ } finally {
75438
+ releaseVariant(entry);
75439
+ }
75440
+ },
75441
+ disconnect: () => {
75442
+ closing ??= (async () => {
75443
+ try {
75444
+ const all = Array.from(variants.values());
75445
+ variants.clear();
75446
+ await Promise.allSettled(all.map((entry) => entry.resolver.disconnect()));
75447
+ } finally {
75448
+ closing = void 0;
75449
+ }
75450
+ })();
75451
+ return closing;
75452
+ },
75453
+ with: (extra) => withExtraTools(resolver, extra)
75454
+ });
75455
+ return resolver;
75456
+ }
75457
+ /** Identity registry for non-serializable option values (e.g. a custom `client.fetch`). */
75458
+ const functionIdentity = /* @__PURE__ */ new WeakMap();
75459
+ let nextFunctionIdentity = 0;
75460
+ /**
75461
+ * Stable key for an options value: JSON with sorted object keys, so two
75462
+ * callbacks returning structurally equal options share one cached variant.
75463
+ * Functions (and other non-plain values) hash by identity — the same
75464
+ * instance maps to the same key, two different instances to different keys —
75465
+ * which is the safe direction: at worst a duplicate cache entry, never a
75466
+ * false merge of different configurations.
75467
+ */
75468
+ function hashOptions(options) {
75469
+ const byIdentity = (value) => {
75470
+ let id = functionIdentity.get(value);
75471
+ if (id === void 0) {
75472
+ id = ++nextFunctionIdentity;
75473
+ functionIdentity.set(value, id);
75474
+ }
75475
+ return `__identity_${id}__`;
75476
+ };
75477
+ const encode = (value) => {
75478
+ if (value === void 0) return "__undefined__";
75479
+ if (typeof value === "function") return byIdentity(value);
75480
+ if (Array.isArray(value)) return value.map(encode);
75481
+ if (typeof value === "object" && value !== null) {
75482
+ const proto = Object.getPrototypeOf(value);
75483
+ if (proto !== Object.prototype && proto !== null) return byIdentity(value);
75484
+ return Object.fromEntries(Object.entries(value).filter(([, entryValue]) => entryValue !== void 0).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([entryKey, entryValue]) => [entryKey, encode(entryValue)]));
75485
+ }
75486
+ return value;
75487
+ };
75488
+ return JSON.stringify(encode(options));
75489
+ }
75490
+ /**
75215
75491
  * Builds the resolver `.with()` returns: resolutions merge the base
75216
75492
  * resolver's tools with `extra` (extra wins on key collision), cache handles
75217
75493
  * delegate to the base, and further `.with()` calls chain.