@mcp-b/global 1.1.3-beta.0 → 1.1.3-beta.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.js CHANGED
@@ -2,6 +2,7 @@ import { IframeChildTransport, TabServerTransport } from "@mcp-b/transports";
2
2
  import { CallToolRequestSchema, GetPromptRequestSchema, ListPromptsRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, Server } from "@mcp-b/webmcp-ts-sdk";
3
3
  import { jsonSchemaToZod } from "@composio/json-schema-to-zod";
4
4
  import { z } from "zod";
5
+ import { zodToJsonSchema as zodToJsonSchema$1 } from "zod-to-json-schema";
5
6
 
6
7
  //#region src/validation.ts
7
8
  /**
@@ -29,44 +30,17 @@ function jsonSchemaToZod$1(jsonSchema) {
29
30
  }
30
31
  /**
31
32
  * Convert Zod schema object to JSON Schema
32
- * Based on react-webmcp implementation
33
+ * Uses zod-to-json-schema package for comprehensive conversion
34
+ *
35
+ * @param schema - Record of Zod type definitions (e.g., { name: z.string(), age: z.number() })
36
+ * @returns JSON Schema object compatible with MCP InputSchema
33
37
  */
34
38
  function zodToJsonSchema(schema) {
35
- const properties = {};
36
- const required = [];
37
- for (const [key, zodType] of Object.entries(schema)) {
38
- const description = zodType.description || void 0;
39
- let type = "string";
40
- let enumValues;
41
- let items;
42
- if (zodType instanceof z.ZodString) type = "string";
43
- else if (zodType instanceof z.ZodNumber) type = "number";
44
- else if (zodType instanceof z.ZodBoolean) type = "boolean";
45
- else if (zodType instanceof z.ZodArray) {
46
- type = "array";
47
- const elementType = zodType.element;
48
- if (elementType instanceof z.ZodString) items = { type: "string" };
49
- else if (elementType instanceof z.ZodNumber) items = { type: "number" };
50
- else if (elementType instanceof z.ZodBoolean) items = { type: "boolean" };
51
- else items = { type: "string" };
52
- } else if (zodType instanceof z.ZodObject) type = "object";
53
- else if (zodType instanceof z.ZodEnum) {
54
- type = "string";
55
- const enumDef = zodType._def;
56
- if (enumDef?.values) enumValues = enumDef.values;
57
- }
58
- const propertySchema = { type };
59
- if (description) propertySchema.description = description;
60
- if (enumValues) propertySchema.enum = enumValues;
61
- if (items) propertySchema.items = items;
62
- properties[key] = propertySchema;
63
- if (!zodType.isOptional()) required.push(key);
64
- }
65
- return {
66
- type: "object",
67
- properties,
68
- ...required.length > 0 && { required }
69
- };
39
+ const { $schema: _,...rest } = zodToJsonSchema$1(z.object(schema), {
40
+ $refStrategy: "none",
41
+ target: "jsonSchema7"
42
+ });
43
+ return rest;
70
44
  }
71
45
  /**
72
46
  * Normalize a schema to both JSON Schema and Zod formats
@@ -713,6 +687,12 @@ var WebModelContext = class {
713
687
  toolUnregisterFunctions;
714
688
  resourceUnregisterFunctions;
715
689
  promptUnregisterFunctions;
690
+ /**
691
+ * Tracks which list change notifications are pending.
692
+ * Uses microtask-based batching to coalesce rapid registrations
693
+ * (e.g., React mount phase) into a single notification per list type.
694
+ */
695
+ pendingNotifications = /* @__PURE__ */ new Set();
716
696
  testingAPI;
717
697
  /**
718
698
  * Creates a new WebModelContext instance.
@@ -819,9 +799,9 @@ var WebModelContext = class {
819
799
  this.updateBridgeTools();
820
800
  this.updateBridgeResources();
821
801
  this.updateBridgePrompts();
822
- this.notifyToolsListChanged();
823
- this.notifyResourcesListChanged();
824
- this.notifyPromptsListChanged();
802
+ this.scheduleListChanged("tools");
803
+ this.scheduleListChanged("resources");
804
+ this.scheduleListChanged("prompts");
825
805
  }
826
806
  /**
827
807
  * Validates and normalizes a resource descriptor.
@@ -898,7 +878,7 @@ var WebModelContext = class {
898
878
  this.dynamicTools.set(tool.name, validatedTool);
899
879
  this.toolRegistrationTimestamps.set(tool.name, now);
900
880
  this.updateBridgeTools();
901
- this.notifyToolsListChanged();
881
+ this.scheduleListChanged("tools");
902
882
  const unregisterFn = () => {
903
883
  console.log(`[Web Model Context] Unregistering tool: ${tool.name}`);
904
884
  if (this.provideContextTools.has(tool.name)) throw new Error(`[Web Model Context] Cannot unregister tool "${tool.name}": This tool was registered via provideContext(). Use provideContext() to update the base tool set.`);
@@ -910,7 +890,7 @@ var WebModelContext = class {
910
890
  this.toolRegistrationTimestamps.delete(tool.name);
911
891
  this.toolUnregisterFunctions.delete(tool.name);
912
892
  this.updateBridgeTools();
913
- this.notifyToolsListChanged();
893
+ this.scheduleListChanged("tools");
914
894
  };
915
895
  this.toolUnregisterFunctions.set(tool.name, unregisterFn);
916
896
  return { unregister: unregisterFn };
@@ -938,7 +918,7 @@ var WebModelContext = class {
938
918
  this.dynamicResources.set(resource.uri, validatedResource);
939
919
  this.resourceRegistrationTimestamps.set(resource.uri, now);
940
920
  this.updateBridgeResources();
941
- this.notifyResourcesListChanged();
921
+ this.scheduleListChanged("resources");
942
922
  const unregisterFn = () => {
943
923
  console.log(`[Web Model Context] Unregistering resource: ${resource.uri}`);
944
924
  if (this.provideContextResources.has(resource.uri)) throw new Error(`[Web Model Context] Cannot unregister resource "${resource.uri}": This resource was registered via provideContext(). Use provideContext() to update the base resource set.`);
@@ -950,7 +930,7 @@ var WebModelContext = class {
950
930
  this.resourceRegistrationTimestamps.delete(resource.uri);
951
931
  this.resourceUnregisterFunctions.delete(resource.uri);
952
932
  this.updateBridgeResources();
953
- this.notifyResourcesListChanged();
933
+ this.scheduleListChanged("resources");
954
934
  };
955
935
  this.resourceUnregisterFunctions.set(resource.uri, unregisterFn);
956
936
  return { unregister: unregisterFn };
@@ -976,7 +956,7 @@ var WebModelContext = class {
976
956
  this.resourceUnregisterFunctions.delete(uri);
977
957
  }
978
958
  this.updateBridgeResources();
979
- this.notifyResourcesListChanged();
959
+ this.scheduleListChanged("resources");
980
960
  }
981
961
  /**
982
962
  * Lists all registered resources in MCP format.
@@ -1029,7 +1009,7 @@ var WebModelContext = class {
1029
1009
  this.dynamicPrompts.set(prompt.name, validatedPrompt);
1030
1010
  this.promptRegistrationTimestamps.set(prompt.name, now);
1031
1011
  this.updateBridgePrompts();
1032
- this.notifyPromptsListChanged();
1012
+ this.scheduleListChanged("prompts");
1033
1013
  const unregisterFn = () => {
1034
1014
  console.log(`[Web Model Context] Unregistering prompt: ${prompt.name}`);
1035
1015
  if (this.provideContextPrompts.has(prompt.name)) throw new Error(`[Web Model Context] Cannot unregister prompt "${prompt.name}": This prompt was registered via provideContext(). Use provideContext() to update the base prompt set.`);
@@ -1041,7 +1021,7 @@ var WebModelContext = class {
1041
1021
  this.promptRegistrationTimestamps.delete(prompt.name);
1042
1022
  this.promptUnregisterFunctions.delete(prompt.name);
1043
1023
  this.updateBridgePrompts();
1044
- this.notifyPromptsListChanged();
1024
+ this.scheduleListChanged("prompts");
1045
1025
  };
1046
1026
  this.promptUnregisterFunctions.set(prompt.name, unregisterFn);
1047
1027
  return { unregister: unregisterFn };
@@ -1067,7 +1047,7 @@ var WebModelContext = class {
1067
1047
  this.promptUnregisterFunctions.delete(name);
1068
1048
  }
1069
1049
  this.updateBridgePrompts();
1070
- this.notifyPromptsListChanged();
1050
+ this.scheduleListChanged("prompts");
1071
1051
  }
1072
1052
  /**
1073
1053
  * Lists all registered prompts in MCP format.
@@ -1107,7 +1087,7 @@ var WebModelContext = class {
1107
1087
  this.toolUnregisterFunctions.delete(name);
1108
1088
  }
1109
1089
  this.updateBridgeTools();
1110
- this.notifyToolsListChanged();
1090
+ this.scheduleListChanged("tools");
1111
1091
  }
1112
1092
  /**
1113
1093
  * Clears all registered context from both buckets (Chromium native API).
@@ -1130,9 +1110,9 @@ var WebModelContext = class {
1130
1110
  this.updateBridgeTools();
1131
1111
  this.updateBridgeResources();
1132
1112
  this.updateBridgePrompts();
1133
- this.notifyToolsListChanged();
1134
- this.notifyResourcesListChanged();
1135
- this.notifyPromptsListChanged();
1113
+ this.scheduleListChanged("tools");
1114
+ this.scheduleListChanged("resources");
1115
+ this.scheduleListChanged("prompts");
1136
1116
  }
1137
1117
  /**
1138
1118
  * Updates the bridge tools map with merged tools from both buckets.
@@ -1216,6 +1196,37 @@ var WebModelContext = class {
1216
1196
  });
1217
1197
  }
1218
1198
  /**
1199
+ * Schedules a list changed notification using microtask batching.
1200
+ * Multiple calls for the same list type within the same task are coalesced
1201
+ * into a single notification. This dramatically reduces notification spam
1202
+ * during React mount/unmount cycles.
1203
+ *
1204
+ * @param listType - The type of list that changed ('tools' | 'resources' | 'prompts')
1205
+ * @private
1206
+ */
1207
+ scheduleListChanged(listType) {
1208
+ if (this.pendingNotifications.has(listType)) return;
1209
+ this.pendingNotifications.add(listType);
1210
+ queueMicrotask(() => {
1211
+ this.pendingNotifications.delete(listType);
1212
+ switch (listType) {
1213
+ case "tools":
1214
+ this.notifyToolsListChanged();
1215
+ break;
1216
+ case "resources":
1217
+ this.notifyResourcesListChanged();
1218
+ break;
1219
+ case "prompts":
1220
+ this.notifyPromptsListChanged();
1221
+ break;
1222
+ default: {
1223
+ const _exhaustive = listType;
1224
+ console.error(`[Web Model Context] Unknown list type: ${_exhaustive}`);
1225
+ }
1226
+ }
1227
+ });
1228
+ }
1229
+ /**
1219
1230
  * Reads a resource by URI (internal use only by MCP bridge).
1220
1231
  * Handles both static resources and URI templates.
1221
1232
  *
@@ -1755,5 +1766,5 @@ if (typeof window !== "undefined" && typeof document !== "undefined") {
1755
1766
  }
1756
1767
 
1757
1768
  //#endregion
1758
- export { cleanupWebModelContext, initializeWebModelContext };
1769
+ export { cleanupWebModelContext, initializeWebModelContext, zodToJsonSchema };
1759
1770
  //# sourceMappingURL=index.js.map