skybridge 0.0.0-dev.d9ee984 → 0.0.0-dev.da22f74

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.
Files changed (338) hide show
  1. package/LICENSE +21 -674
  2. package/README.md +152 -2
  3. package/bin/run.js +5 -0
  4. package/dist/cli/detect-port.d.ts +18 -0
  5. package/dist/cli/detect-port.js +61 -0
  6. package/dist/cli/detect-port.js.map +1 -0
  7. package/dist/cli/header.d.ts +4 -0
  8. package/dist/cli/header.js +6 -0
  9. package/dist/cli/header.js.map +1 -0
  10. package/dist/cli/run-command.d.ts +2 -0
  11. package/dist/cli/run-command.js +43 -0
  12. package/dist/cli/run-command.js.map +1 -0
  13. package/dist/cli/telemetry.d.ts +7 -0
  14. package/dist/cli/telemetry.js +123 -0
  15. package/dist/cli/telemetry.js.map +1 -0
  16. package/dist/cli/tunnel-control-server.d.ts +9 -0
  17. package/dist/cli/tunnel-control-server.js +31 -0
  18. package/dist/cli/tunnel-control-server.js.map +1 -0
  19. package/dist/cli/tunnel-control-server.test.d.ts +1 -0
  20. package/dist/cli/tunnel-control-server.test.js +39 -0
  21. package/dist/cli/tunnel-control-server.test.js.map +1 -0
  22. package/dist/cli/tunnel-handler.d.ts +3 -0
  23. package/dist/cli/tunnel-handler.js +48 -0
  24. package/dist/cli/tunnel-handler.js.map +1 -0
  25. package/dist/cli/tunnel-handler.test.d.ts +1 -0
  26. package/dist/cli/tunnel-handler.test.js +105 -0
  27. package/dist/cli/tunnel-handler.test.js.map +1 -0
  28. package/dist/cli/tunnel.d.ts +57 -0
  29. package/dist/cli/tunnel.js +154 -0
  30. package/dist/cli/tunnel.js.map +1 -0
  31. package/dist/cli/tunnel.test.d.ts +1 -0
  32. package/dist/cli/tunnel.test.js +190 -0
  33. package/dist/cli/tunnel.test.js.map +1 -0
  34. package/dist/cli/types.d.ts +5 -0
  35. package/dist/cli/types.js +2 -0
  36. package/dist/cli/types.js.map +1 -0
  37. package/dist/cli/use-execute-steps.d.ts +11 -0
  38. package/dist/cli/use-execute-steps.js +36 -0
  39. package/dist/cli/use-execute-steps.js.map +1 -0
  40. package/dist/cli/use-messages.d.ts +3 -0
  41. package/dist/cli/use-messages.js +11 -0
  42. package/dist/cli/use-messages.js.map +1 -0
  43. package/dist/cli/use-nodemon.d.ts +2 -0
  44. package/dist/cli/use-nodemon.js +73 -0
  45. package/dist/cli/use-nodemon.js.map +1 -0
  46. package/dist/cli/use-open-browser.d.ts +1 -0
  47. package/dist/cli/use-open-browser.js +44 -0
  48. package/dist/cli/use-open-browser.js.map +1 -0
  49. package/dist/cli/use-tunnel.d.ts +14 -0
  50. package/dist/cli/use-tunnel.js +131 -0
  51. package/dist/cli/use-tunnel.js.map +1 -0
  52. package/dist/cli/use-typescript-check.d.ts +9 -0
  53. package/dist/cli/use-typescript-check.js +94 -0
  54. package/dist/cli/use-typescript-check.js.map +1 -0
  55. package/dist/commands/build.d.ts +9 -0
  56. package/dist/commands/build.js +102 -0
  57. package/dist/commands/build.js.map +1 -0
  58. package/dist/commands/dev.d.ts +12 -0
  59. package/dist/commands/dev.js +80 -0
  60. package/dist/commands/dev.js.map +1 -0
  61. package/dist/commands/start.d.ts +9 -0
  62. package/dist/commands/start.js +49 -0
  63. package/dist/commands/start.js.map +1 -0
  64. package/dist/commands/telemetry/disable.d.ts +5 -0
  65. package/dist/commands/telemetry/disable.js +14 -0
  66. package/dist/commands/telemetry/disable.js.map +1 -0
  67. package/dist/commands/telemetry/enable.d.ts +5 -0
  68. package/dist/commands/telemetry/enable.js +14 -0
  69. package/dist/commands/telemetry/enable.js.map +1 -0
  70. package/dist/commands/telemetry/status.d.ts +5 -0
  71. package/dist/commands/telemetry/status.js +14 -0
  72. package/dist/commands/telemetry/status.js.map +1 -0
  73. package/dist/server/asset-base-url-transform-plugin.d.ts +10 -0
  74. package/dist/server/asset-base-url-transform-plugin.js +33 -0
  75. package/dist/server/asset-base-url-transform-plugin.js.map +1 -0
  76. package/dist/server/asset-base-url-transform-plugin.test.d.ts +1 -0
  77. package/dist/server/asset-base-url-transform-plugin.test.js +84 -0
  78. package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -0
  79. package/dist/server/content-helpers.d.ts +27 -0
  80. package/dist/server/content-helpers.js +46 -0
  81. package/dist/server/content-helpers.js.map +1 -0
  82. package/dist/server/content-helpers.test.d.ts +1 -0
  83. package/dist/server/content-helpers.test.js +70 -0
  84. package/dist/server/content-helpers.test.js.map +1 -0
  85. package/dist/server/express.d.ts +11 -0
  86. package/dist/server/express.js +101 -0
  87. package/dist/server/express.js.map +1 -0
  88. package/dist/server/express.test.d.ts +1 -0
  89. package/dist/server/express.test.js +430 -0
  90. package/dist/server/express.test.js.map +1 -0
  91. package/dist/server/index.d.ts +6 -3
  92. package/dist/server/index.js +3 -3
  93. package/dist/server/index.js.map +1 -1
  94. package/dist/server/inferUtilityTypes.d.ts +64 -0
  95. package/dist/server/inferUtilityTypes.js +2 -0
  96. package/dist/server/inferUtilityTypes.js.map +1 -0
  97. package/dist/server/metric.d.ts +14 -0
  98. package/dist/server/metric.js +62 -0
  99. package/dist/server/metric.js.map +1 -0
  100. package/dist/server/middleware.d.ts +124 -3
  101. package/dist/server/middleware.js +88 -42
  102. package/dist/server/middleware.js.map +1 -1
  103. package/dist/server/middleware.test-d.d.ts +1 -0
  104. package/dist/server/middleware.test-d.js +75 -0
  105. package/dist/server/middleware.test-d.js.map +1 -0
  106. package/dist/server/middleware.test.d.ts +1 -0
  107. package/dist/server/middleware.test.js +493 -0
  108. package/dist/server/middleware.test.js.map +1 -0
  109. package/dist/server/server.d.ts +194 -10
  110. package/dist/server/server.js +455 -57
  111. package/dist/server/server.js.map +1 -1
  112. package/dist/server/templateHelper.d.ts +16 -0
  113. package/dist/server/templateHelper.js +11 -0
  114. package/dist/server/templateHelper.js.map +1 -0
  115. package/dist/server/templates.generated.d.ts +4 -0
  116. package/dist/server/templates.generated.js +47 -0
  117. package/dist/server/templates.generated.js.map +1 -0
  118. package/dist/server/tunnel-proxy-router.d.ts +7 -0
  119. package/dist/server/tunnel-proxy-router.js +110 -0
  120. package/dist/server/tunnel-proxy-router.js.map +1 -0
  121. package/dist/server/tunnel-proxy-router.test.d.ts +1 -0
  122. package/dist/server/tunnel-proxy-router.test.js +229 -0
  123. package/dist/server/tunnel-proxy-router.test.js.map +1 -0
  124. package/dist/server/viewsDevServer.d.ts +14 -0
  125. package/dist/server/viewsDevServer.js +45 -0
  126. package/dist/server/viewsDevServer.js.map +1 -0
  127. package/dist/test/utils.d.ts +127 -0
  128. package/dist/test/utils.js +247 -0
  129. package/dist/test/utils.js.map +1 -0
  130. package/dist/test/view.test.d.ts +1 -0
  131. package/dist/test/view.test.js +523 -0
  132. package/dist/test/view.test.js.map +1 -0
  133. package/dist/version.d.ts +1 -0
  134. package/dist/version.js +3 -0
  135. package/dist/version.js.map +1 -0
  136. package/dist/web/bridges/apps-sdk/adaptor.d.ts +24 -0
  137. package/dist/web/bridges/apps-sdk/adaptor.js +93 -0
  138. package/dist/web/bridges/apps-sdk/adaptor.js.map +1 -0
  139. package/dist/web/bridges/apps-sdk/bridge.d.ts +10 -0
  140. package/dist/web/bridges/apps-sdk/bridge.js +46 -0
  141. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -0
  142. package/dist/web/bridges/apps-sdk/index.d.ts +5 -0
  143. package/dist/web/bridges/apps-sdk/index.js +5 -0
  144. package/dist/web/bridges/apps-sdk/index.js.map +1 -0
  145. package/dist/web/bridges/apps-sdk/types.d.ts +126 -0
  146. package/dist/web/bridges/apps-sdk/types.js +10 -0
  147. package/dist/web/bridges/apps-sdk/types.js.map +1 -0
  148. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +2 -0
  149. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +7 -0
  150. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -0
  151. package/dist/web/bridges/get-adaptor.d.ts +2 -0
  152. package/dist/web/bridges/get-adaptor.js +8 -0
  153. package/dist/web/bridges/get-adaptor.js.map +1 -0
  154. package/dist/web/bridges/index.d.ts +5 -0
  155. package/dist/web/bridges/index.js +6 -0
  156. package/dist/web/bridges/index.js.map +1 -0
  157. package/dist/web/bridges/mcp-app/adaptor.d.ts +48 -0
  158. package/dist/web/bridges/mcp-app/adaptor.js +268 -0
  159. package/dist/web/bridges/mcp-app/adaptor.js.map +1 -0
  160. package/dist/web/bridges/mcp-app/bridge.d.ts +26 -0
  161. package/dist/web/bridges/mcp-app/bridge.js +102 -0
  162. package/dist/web/bridges/mcp-app/bridge.js.map +1 -0
  163. package/dist/web/bridges/mcp-app/index.d.ts +4 -0
  164. package/dist/web/bridges/mcp-app/index.js +4 -0
  165. package/dist/web/bridges/mcp-app/index.js.map +1 -0
  166. package/dist/web/bridges/mcp-app/types.d.ts +8 -0
  167. package/dist/web/bridges/mcp-app/types.js +2 -0
  168. package/dist/web/bridges/mcp-app/types.js.map +1 -0
  169. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +7 -0
  170. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +7 -0
  171. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -0
  172. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.d.ts +1 -0
  173. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +26 -0
  174. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -0
  175. package/dist/web/bridges/types.d.ts +109 -0
  176. package/dist/web/bridges/types.js +2 -0
  177. package/dist/web/bridges/types.js.map +1 -0
  178. package/dist/web/bridges/use-host-context.d.ts +2 -0
  179. package/dist/web/bridges/use-host-context.js +8 -0
  180. package/dist/web/bridges/use-host-context.js.map +1 -0
  181. package/dist/web/components/modal-provider.d.ts +4 -0
  182. package/dist/web/components/modal-provider.js +45 -0
  183. package/dist/web/components/modal-provider.js.map +1 -0
  184. package/dist/web/create-store.d.ts +3 -0
  185. package/dist/web/create-store.js +38 -0
  186. package/dist/web/create-store.js.map +1 -0
  187. package/dist/web/create-store.test.d.ts +1 -0
  188. package/dist/web/create-store.test.js +129 -0
  189. package/dist/web/create-store.test.js.map +1 -0
  190. package/dist/web/data-llm.d.ts +14 -0
  191. package/dist/web/data-llm.js +72 -0
  192. package/dist/web/data-llm.js.map +1 -0
  193. package/dist/web/data-llm.test.d.ts +1 -0
  194. package/dist/web/data-llm.test.js +142 -0
  195. package/dist/web/data-llm.test.js.map +1 -0
  196. package/dist/web/generate-helpers.d.ts +118 -0
  197. package/dist/web/generate-helpers.js +113 -0
  198. package/dist/web/generate-helpers.js.map +1 -0
  199. package/dist/web/generate-helpers.test-d.d.ts +1 -0
  200. package/dist/web/generate-helpers.test-d.js +209 -0
  201. package/dist/web/generate-helpers.test-d.js.map +1 -0
  202. package/dist/web/generate-helpers.test.d.ts +1 -0
  203. package/dist/web/generate-helpers.test.js +17 -0
  204. package/dist/web/generate-helpers.test.js.map +1 -0
  205. package/dist/web/helpers/state.d.ts +7 -0
  206. package/dist/web/helpers/state.js +45 -0
  207. package/dist/web/helpers/state.js.map +1 -0
  208. package/dist/web/helpers/state.test.d.ts +1 -0
  209. package/dist/web/helpers/state.test.js +53 -0
  210. package/dist/web/helpers/state.test.js.map +1 -0
  211. package/dist/web/hooks/index.d.ts +11 -0
  212. package/dist/web/hooks/index.js +12 -0
  213. package/dist/web/hooks/index.js.map +1 -0
  214. package/dist/web/hooks/test/utils.d.ts +16 -0
  215. package/dist/web/hooks/test/utils.js +64 -0
  216. package/dist/web/hooks/test/utils.js.map +1 -0
  217. package/dist/web/hooks/use-call-tool.d.ts +101 -0
  218. package/dist/web/hooks/use-call-tool.js +68 -0
  219. package/dist/web/hooks/use-call-tool.js.map +1 -0
  220. package/dist/web/hooks/use-call-tool.test-d.d.ts +1 -0
  221. package/dist/web/hooks/use-call-tool.test-d.js +104 -0
  222. package/dist/web/hooks/use-call-tool.test-d.js.map +1 -0
  223. package/dist/web/hooks/use-call-tool.test.d.ts +1 -0
  224. package/dist/web/hooks/use-call-tool.test.js +190 -0
  225. package/dist/web/hooks/use-call-tool.test.js.map +1 -0
  226. package/dist/web/hooks/use-display-mode.d.ts +4 -0
  227. package/dist/web/hooks/use-display-mode.js +9 -0
  228. package/dist/web/hooks/use-display-mode.js.map +1 -0
  229. package/dist/web/hooks/use-display-mode.test-d.d.ts +1 -0
  230. package/dist/web/hooks/use-display-mode.test-d.js +8 -0
  231. package/dist/web/hooks/use-display-mode.test-d.js.map +1 -0
  232. package/dist/web/hooks/use-display-mode.test.d.ts +1 -0
  233. package/dist/web/hooks/use-display-mode.test.js +41 -0
  234. package/dist/web/hooks/use-display-mode.test.js.map +1 -0
  235. package/dist/web/hooks/use-files.d.ts +7 -0
  236. package/dist/web/hooks/use-files.js +10 -0
  237. package/dist/web/hooks/use-files.js.map +1 -0
  238. package/dist/web/hooks/use-files.test.d.ts +1 -0
  239. package/dist/web/hooks/use-files.test.js +54 -0
  240. package/dist/web/hooks/use-files.test.js.map +1 -0
  241. package/dist/web/hooks/use-layout.d.ts +22 -0
  242. package/dist/web/hooks/use-layout.js +23 -0
  243. package/dist/web/hooks/use-layout.js.map +1 -0
  244. package/dist/web/hooks/use-layout.test.d.ts +1 -0
  245. package/dist/web/hooks/use-layout.test.js +96 -0
  246. package/dist/web/hooks/use-layout.test.js.map +1 -0
  247. package/dist/web/hooks/use-open-external.d.ts +3 -0
  248. package/dist/web/hooks/use-open-external.js +8 -0
  249. package/dist/web/hooks/use-open-external.js.map +1 -0
  250. package/dist/web/hooks/use-open-external.test.d.ts +1 -0
  251. package/dist/web/hooks/use-open-external.test.js +65 -0
  252. package/dist/web/hooks/use-open-external.test.js.map +1 -0
  253. package/dist/web/hooks/use-request-modal.d.ts +9 -0
  254. package/dist/web/hooks/use-request-modal.js +16 -0
  255. package/dist/web/hooks/use-request-modal.js.map +1 -0
  256. package/dist/web/hooks/use-request-modal.test.d.ts +1 -0
  257. package/dist/web/hooks/use-request-modal.test.js +61 -0
  258. package/dist/web/hooks/use-request-modal.test.js.map +1 -0
  259. package/dist/web/hooks/use-send-follow-up-message.d.ts +1 -0
  260. package/dist/web/hooks/use-send-follow-up-message.js +8 -0
  261. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -0
  262. package/dist/web/hooks/use-set-open-in-app-url.d.ts +1 -0
  263. package/dist/web/hooks/use-set-open-in-app-url.js +8 -0
  264. package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -0
  265. package/dist/web/hooks/use-set-open-in-app-url.test.d.ts +1 -0
  266. package/dist/web/hooks/use-set-open-in-app-url.test.js +43 -0
  267. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -0
  268. package/dist/web/hooks/use-tool-info.d.ts +36 -0
  269. package/dist/web/hooks/use-tool-info.js +26 -0
  270. package/dist/web/hooks/use-tool-info.js.map +1 -0
  271. package/dist/web/hooks/use-tool-info.test-d.d.ts +1 -0
  272. package/dist/web/hooks/use-tool-info.test-d.js +109 -0
  273. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -0
  274. package/dist/web/hooks/use-tool-info.test.d.ts +1 -0
  275. package/dist/web/hooks/use-tool-info.test.js +130 -0
  276. package/dist/web/hooks/use-tool-info.test.js.map +1 -0
  277. package/dist/web/hooks/use-user.d.ts +18 -0
  278. package/dist/web/hooks/use-user.js +35 -0
  279. package/dist/web/hooks/use-user.js.map +1 -0
  280. package/dist/web/hooks/use-user.test.d.ts +1 -0
  281. package/dist/web/hooks/use-user.test.js +122 -0
  282. package/dist/web/hooks/use-user.test.js.map +1 -0
  283. package/dist/web/hooks/use-view-state.d.ts +4 -0
  284. package/dist/web/hooks/use-view-state.js +32 -0
  285. package/dist/web/hooks/use-view-state.js.map +1 -0
  286. package/dist/web/hooks/use-view-state.test.d.ts +1 -0
  287. package/dist/web/hooks/use-view-state.test.js +177 -0
  288. package/dist/web/hooks/use-view-state.test.js.map +1 -0
  289. package/dist/web/index.d.ts +6 -3
  290. package/dist/web/index.js +6 -3
  291. package/dist/web/index.js.map +1 -1
  292. package/dist/web/mount-view.d.ts +1 -0
  293. package/dist/web/mount-view.js +27 -0
  294. package/dist/web/mount-view.js.map +1 -0
  295. package/dist/web/plugin/data-llm.test.d.ts +1 -0
  296. package/dist/web/plugin/data-llm.test.js +81 -0
  297. package/dist/web/plugin/data-llm.test.js.map +1 -0
  298. package/dist/web/plugin/plugin.d.ts +5 -0
  299. package/dist/web/plugin/plugin.js +156 -0
  300. package/dist/web/plugin/plugin.js.map +1 -0
  301. package/dist/web/plugin/scan-views.d.ts +16 -0
  302. package/dist/web/plugin/scan-views.js +88 -0
  303. package/dist/web/plugin/scan-views.js.map +1 -0
  304. package/dist/web/plugin/scan-views.test.d.ts +1 -0
  305. package/dist/web/plugin/scan-views.test.js +99 -0
  306. package/dist/web/plugin/scan-views.test.js.map +1 -0
  307. package/dist/web/plugin/transform-data-llm.d.ts +12 -0
  308. package/dist/web/plugin/transform-data-llm.js +96 -0
  309. package/dist/web/plugin/transform-data-llm.js.map +1 -0
  310. package/dist/web/plugin/transform-data-llm.test.d.ts +1 -0
  311. package/dist/web/plugin/transform-data-llm.test.js +81 -0
  312. package/dist/web/plugin/transform-data-llm.test.js.map +1 -0
  313. package/dist/web/plugin/validate-view.d.ts +1 -0
  314. package/dist/web/plugin/validate-view.js +9 -0
  315. package/dist/web/plugin/validate-view.js.map +1 -0
  316. package/dist/web/plugin/validate-view.test.d.ts +1 -0
  317. package/dist/web/plugin/validate-view.test.js +24 -0
  318. package/dist/web/plugin/validate-view.test.js.map +1 -0
  319. package/dist/web/proxy.d.ts +1 -0
  320. package/dist/web/proxy.js +52 -0
  321. package/dist/web/proxy.js.map +1 -0
  322. package/dist/web/types.d.ts +13 -92
  323. package/dist/web/types.js +1 -9
  324. package/dist/web/types.js.map +1 -1
  325. package/package.json +80 -21
  326. package/tsconfig.base.json +33 -0
  327. package/dist/server/widgetsDevServer.d.ts +0 -9
  328. package/dist/server/widgetsDevServer.js +0 -36
  329. package/dist/server/widgetsDevServer.js.map +0 -1
  330. package/dist/web/mount-widget.d.ts +0 -1
  331. package/dist/web/mount-widget.js +0 -10
  332. package/dist/web/mount-widget.js.map +0 -1
  333. package/dist/web/use-openai-global.d.ts +0 -2
  334. package/dist/web/use-openai-global.js +0 -21
  335. package/dist/web/use-openai-global.js.map +0 -1
  336. package/dist/web/use-tool-output.d.ts +0 -3
  337. package/dist/web/use-tool-output.js +0 -5
  338. package/dist/web/use-tool-output.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-helpers.test-d.js","sourceRoot":"","sources":["../../src/web/generate-helpers.test-d.ts"],"names":[],"mappings":"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","sourcesContent":["import { expectTypeOf, test } from \"vitest\";\nimport type {\n InferTools,\n ToolInput,\n ToolNames,\n ToolOutput,\n ToolResponseMetadata,\n} from \"../server/index.js\";\nimport { createInterfaceTestServer, createTestServer } from \"../test/utils.js\";\nimport { generateHelpers } from \"./generate-helpers.js\";\n\nconst server = createTestServer();\ntype TestServer = typeof server;\n\nconst interfaceServer = createInterfaceTestServer();\ntype InterfaceTestServer = typeof interfaceServer;\n\ntest(\"InferTools extracts the tool registry type (views + registerTool)\", () => {\n type Tools = InferTools<TestServer>;\n\n expectTypeOf<Tools>().toHaveProperty(\"search-trip\");\n expectTypeOf<Tools>().toHaveProperty(\"get-trip-details\");\n expectTypeOf<Tools>().toHaveProperty(\"no-input-view\");\n expectTypeOf<Tools>().toHaveProperty(\"calculate-price\");\n expectTypeOf<Tools>().toHaveProperty(\"inferred-output-view\");\n expectTypeOf<Tools>().toHaveProperty(\"inferred-tool\");\n expectTypeOf<Tools>().toHaveProperty(\"view-with-metadata\");\n expectTypeOf<Tools>().toHaveProperty(\"tool-with-metadata\");\n expectTypeOf<Tools>().toHaveProperty(\"view-with-mixed-returns\");\n});\n\ntest(\"ToolNames returns a union of tool name literals (views + registerTool)\", () => {\n type Names = ToolNames<TestServer>;\n\n expectTypeOf<Names>().toEqualTypeOf<\n | \"search-trip\"\n | \"get-trip-details\"\n | \"no-input-view\"\n | \"calculate-price\"\n | \"inferred-output-view\"\n | \"inferred-tool\"\n | \"view-with-metadata\"\n | \"tool-with-metadata\"\n | \"view-with-mixed-returns\"\n >();\n});\n\ntest(\"ToolInput extracts the correct input type from Zod schema\", () => {\n type SearchInput = ToolInput<TestServer, \"search-trip\">;\n\n expectTypeOf<SearchInput>().toEqualTypeOf<{\n destination: string;\n departureDate?: string | undefined;\n maxPrice?: number | undefined;\n }>();\n\n type DetailsInput = ToolInput<TestServer, \"get-trip-details\">;\n\n expectTypeOf<DetailsInput>().toEqualTypeOf<{\n tripId: string;\n }>();\n\n type CalculateInput = ToolInput<TestServer, \"calculate-price\">;\n\n expectTypeOf<CalculateInput>().toEqualTypeOf<{\n tripId: string;\n passengers: number;\n }>();\n});\n\ntest(\"ToolOutput extracts the correct output type from callback's structuredContent\", () => {\n type SearchOutput = ToolOutput<TestServer, \"search-trip\">;\n\n expectTypeOf<SearchOutput>().toEqualTypeOf<{\n results: Array<{\n id: string;\n name: string;\n price: number;\n }>;\n totalCount: number;\n }>();\n\n type DetailsOutput = ToolOutput<TestServer, \"get-trip-details\">;\n\n expectTypeOf<DetailsOutput>().toEqualTypeOf<{\n name: string;\n description: string;\n images: string[];\n }>();\n\n // Note: outputSchema has totalPrice: z.string(), but callback returns number\n // Type is inferred from callback, so totalPrice is number\n type CalculateOutput = ToolOutput<TestServer, \"calculate-price\">;\n\n expectTypeOf<CalculateOutput>().toEqualTypeOf<{\n totalPrice: number;\n currency: string;\n }>();\n\n type NoInputOutput = ToolOutput<TestServer, \"no-input-view\">;\n expectTypeOf<NoInputOutput>().toEqualTypeOf<Record<never, unknown>>();\n});\n\ntest(\"ToolOutput extracts the correct output type from callback (inferred)\", () => {\n type InferredViewOutput = ToolOutput<TestServer, \"inferred-output-view\">;\n\n expectTypeOf<InferredViewOutput>().toEqualTypeOf<{\n inferredResults: { id: string; score: number }[];\n inferredCount: number;\n }>();\n\n type InferredToolOutput = ToolOutput<TestServer, \"inferred-tool\">;\n\n expectTypeOf<InferredToolOutput>().toEqualTypeOf<{\n itemDetails: { name: string; available: boolean };\n fetchedAt: string;\n }>();\n});\n\ntest(\"generateHelpers provides autocomplete for tool names (views + registerTool)\", () => {\n const { useCallTool } = generateHelpers<TestServer>();\n\n useCallTool(\"search-trip\");\n useCallTool(\"get-trip-details\");\n useCallTool(\"no-input-view\");\n useCallTool(\"calculate-price\");\n useCallTool(\"inferred-output-view\");\n useCallTool(\"inferred-tool\");\n useCallTool(\"view-with-metadata\");\n useCallTool(\"tool-with-metadata\");\n useCallTool(\"view-with-mixed-returns\");\n\n // @ts-expect-error - \"invalid-name\" is not a valid tool name\n useCallTool(\"invalid-name\");\n});\n\ntest(\"useCallTool returns correctly typed callTool function\", () => {\n const { useCallTool } = generateHelpers<TestServer>();\n const { callTool } = useCallTool(\"search-trip\");\n\n callTool({ destination: \"Spain\" });\n callTool({ destination: \"France\", departureDate: \"2024-06-01\" });\n callTool({ destination: \"Italy\", maxPrice: 1000 });\n\n const { callTool: calculateTool } = useCallTool(\"calculate-price\");\n calculateTool({ tripId: \"123\", passengers: 2 });\n});\n\ntest(\"callTool can be called without args for tools with no required inputs\", () => {\n const { useCallTool } = generateHelpers<TestServer>();\n const { callTool, callToolAsync } = useCallTool(\"no-input-view\");\n\n callTool();\n\n callTool({});\n\n callToolAsync();\n callToolAsync({});\n});\n\ntest(\"callTool requires args for tools with required inputs\", () => {\n const { useCallTool } = generateHelpers<TestServer>();\n const { callTool } = useCallTool(\"search-trip\");\n\n // @ts-expect-error - \"destination\" is required\n callTool();\n\n // @ts-expect-error - \"destination\" is required\n callTool({});\n\n // This should work\n callTool({ destination: \"Spain\" });\n});\n\ntest(\"callTool supports sideEffects for tools with required inputs\", () => {\n const { useCallTool } = generateHelpers<TestServer>();\n const { callTool } = useCallTool(\"search-trip\");\n\n callTool(\n { destination: \"Spain\" },\n {\n onSuccess: (response, args) => {\n expectTypeOf(response.structuredContent.results).toBeArray();\n expectTypeOf(args.destination).toBeString();\n },\n onError: (error, args) => {\n expectTypeOf(error).toBeUnknown();\n expectTypeOf(args.destination).toBeString();\n },\n onSettled: (response, error, args) => {\n if (response) {\n expectTypeOf(response.structuredContent.totalCount).toBeNumber();\n }\n expectTypeOf(error).toBeUnknown();\n expectTypeOf(args.destination).toBeString();\n },\n },\n );\n});\n\ntest(\"callTool supports sideEffects for tools with no required inputs\", () => {\n const { useCallTool } = generateHelpers<TestServer>();\n const { callTool } = useCallTool(\"no-input-view\");\n\n callTool({\n onSuccess: (response) => {\n expectTypeOf(response).toHaveProperty(\"structuredContent\");\n },\n });\n\n callTool(\n {},\n {\n onSuccess: (response) => {\n expectTypeOf(response).toHaveProperty(\"structuredContent\");\n },\n },\n );\n});\n\ntest(\"callToolAsync returns correctly typed promise\", () => {\n const { useCallTool } = generateHelpers<TestServer>();\n\n const { callToolAsync: searchAsync } = useCallTool(\"search-trip\");\n const searchPromise = searchAsync({ destination: \"Spain\" });\n expectTypeOf(searchPromise).resolves.toHaveProperty(\"structuredContent\");\n\n const { callToolAsync: noInputAsync } = useCallTool(\"no-input-view\");\n const noInputPromise = noInputAsync();\n expectTypeOf(noInputPromise).resolves.toHaveProperty(\"structuredContent\");\n});\n\ntest(\"useCallTool returns correctly typed data\", () => {\n const { useCallTool } = generateHelpers<TestServer>();\n const { data } = useCallTool(\"search-trip\");\n\n if (data) {\n expectTypeOf(data.structuredContent).toExtend<{\n results: Array<{\n id: string;\n name: string;\n price: number;\n }>;\n totalCount: number;\n }>();\n\n expectTypeOf(data.structuredContent.results).toBeArray();\n expectTypeOf(data.structuredContent.totalCount).toBeNumber();\n }\n});\n\ntest(\"useCallTool returns correctly typed data for callback-inferred outputs\", () => {\n const { useCallTool } = generateHelpers<TestServer>();\n\n const { data: viewData } = useCallTool(\"inferred-output-view\");\n if (viewData) {\n expectTypeOf(viewData.structuredContent).toExtend<{\n inferredResults: { id: string; score: number }[];\n inferredCount: number;\n }>();\n }\n\n const { data: toolData } = useCallTool(\"inferred-tool\");\n if (toolData) {\n expectTypeOf(toolData.structuredContent).toExtend<{\n itemDetails: { name: string; available: boolean };\n fetchedAt: string;\n }>();\n }\n});\n\ntest(\"generateHelpers provides autocomplete for tool names in useToolInfo (views + registerTool)\", () => {\n const { useToolInfo } = generateHelpers<TestServer>();\n\n useToolInfo<\"search-trip\">();\n useToolInfo<\"get-trip-details\">();\n useToolInfo<\"no-input-view\">();\n useToolInfo<\"calculate-price\">();\n useToolInfo<\"inferred-output-view\">();\n useToolInfo<\"inferred-tool\">();\n useToolInfo<\"view-with-metadata\">();\n useToolInfo<\"tool-with-metadata\">();\n useToolInfo<\"view-with-mixed-returns\">();\n\n // @ts-expect-error - \"invalid-name\" is not a valid tool name\n useToolInfo<\"invalid-name\">();\n});\n\ntest(\"useToolInfo infers input and output types\", () => {\n const { useToolInfo } = generateHelpers<TestServer>();\n const toolInfo = useToolInfo<\"search-trip\">();\n\n // Input is only available when not in idle state\n if (!(toolInfo.status === \"idle\")) {\n expectTypeOf(toolInfo.input).toExtend<\n ToolInput<TestServer, \"search-trip\">\n >();\n }\n\n if (toolInfo.status === \"success\") {\n expectTypeOf(toolInfo.output).toExtend<\n ToolOutput<TestServer, \"search-trip\">\n >();\n expectTypeOf(toolInfo.output.results).toBeArray();\n expectTypeOf(toolInfo.output.totalCount).toBeNumber();\n }\n});\n\ntest(\"ToolResponseMetadata extracts _meta type from callback\", () => {\n type ViewMeta = ToolResponseMetadata<TestServer, \"view-with-metadata\">;\n expectTypeOf<ViewMeta>().toEqualTypeOf<{\n requestId: string;\n timestamp: number;\n cached: boolean;\n }>();\n\n type ToolMeta = ToolResponseMetadata<TestServer, \"tool-with-metadata\">;\n expectTypeOf<ToolMeta>().toEqualTypeOf<{\n executionTime: number;\n source: string;\n }>();\n\n type SearchMeta = ToolResponseMetadata<TestServer, \"search-trip\">;\n expectTypeOf<SearchMeta>().toBeUnknown();\n});\n\ntest(\"useToolInfo infers responseMetadata type from generateHelpers\", () => {\n const { useToolInfo } = generateHelpers<TestServer>();\n const toolInfo = useToolInfo<\"view-with-metadata\">();\n\n if (toolInfo.isSuccess) {\n expectTypeOf(toolInfo.responseMetadata.requestId).toBeString();\n expectTypeOf(toolInfo.responseMetadata.timestamp).toBeNumber();\n expectTypeOf(toolInfo.responseMetadata.cached).toBeBoolean();\n }\n});\n\ntest(\"ToolResponseMetadata extracts _meta from mixed return paths\", () => {\n // View has multiple return paths: some with _meta, some without\n // ExtractMeta should still infer the _meta type from branches that have it\n type MixedMeta = ToolResponseMetadata<TestServer, \"view-with-mixed-returns\">;\n expectTypeOf<MixedMeta>().toEqualTypeOf<{\n processedAt: number;\n region: string;\n }>();\n});\n\ntest(\"ToolOutput extracts correct type when using interface declaration\", () => {\n type InterfaceViewOutput = ToolOutput<InterfaceTestServer, \"interface-view\">;\n\n expectTypeOf<InterfaceViewOutput>().toHaveProperty(\"itemName\");\n expectTypeOf<InterfaceViewOutput[\"itemName\"]>().toBeString();\n expectTypeOf<InterfaceViewOutput[\"quantity\"]>().toBeNumber();\n});\n\ntest(\"ToolResponseMetadata extracts correct type when using interface declaration\", () => {\n type InterfaceViewMeta = ToolResponseMetadata<\n InterfaceTestServer,\n \"interface-view\"\n >;\n\n expectTypeOf<InterfaceViewMeta>().toHaveProperty(\"processedBy\");\n expectTypeOf<InterfaceViewMeta[\"processedBy\"]>().toBeString();\n expectTypeOf<InterfaceViewMeta[\"version\"]>().toBeNumber();\n});\n\ntest(\"generateHelpers works with interface-typed server\", () => {\n const { useCallTool, useToolInfo } = generateHelpers<InterfaceTestServer>();\n\n const { data } = useCallTool(\"interface-view\");\n if (data) {\n expectTypeOf(data.structuredContent.itemName).toBeString();\n expectTypeOf(data.structuredContent.quantity).toBeNumber();\n }\n\n const toolInfo = useToolInfo<\"interface-view\">();\n if (toolInfo.isSuccess) {\n expectTypeOf(toolInfo.output.itemName).toBeString();\n expectTypeOf(toolInfo.output.quantity).toBeNumber();\n expectTypeOf(toolInfo.responseMetadata.processedBy).toBeString();\n expectTypeOf(toolInfo.responseMetadata.version).toBeNumber();\n }\n});\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { createMinimalTestServer } from "../test/utils.js";
3
+ import { generateHelpers } from "./generate-helpers.js";
4
+ const server = createMinimalTestServer();
5
+ describe("generateHelpers", () => {
6
+ it("should return an object with useCallTool hook", () => {
7
+ const hooks = generateHelpers();
8
+ expect(hooks).toHaveProperty("useCallTool");
9
+ expect(typeof hooks.useCallTool).toBe("function");
10
+ });
11
+ it("should return an object with useToolInfo hook", () => {
12
+ const hooks = generateHelpers();
13
+ expect(hooks).toHaveProperty("useToolInfo");
14
+ expect(typeof hooks.useToolInfo).toBe("function");
15
+ });
16
+ });
17
+ //# sourceMappingURL=generate-helpers.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-helpers.test.js","sourceRoot":"","sources":["../../src/web/generate-helpers.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,MAAM,GAAG,uBAAuB,EAAE,CAAC;AAGzC,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,KAAK,GAAG,eAAe,EAAc,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;QAC5C,MAAM,CAAC,OAAO,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,KAAK,GAAG,eAAe,EAAc,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;QAC5C,MAAM,CAAC,OAAO,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { createMinimalTestServer } from \"../test/utils.js\";\nimport { generateHelpers } from \"./generate-helpers.js\";\n\nconst server = createMinimalTestServer();\ntype TestServer = typeof server;\n\ndescribe(\"generateHelpers\", () => {\n it(\"should return an object with useCallTool hook\", () => {\n const hooks = generateHelpers<TestServer>();\n expect(hooks).toHaveProperty(\"useCallTool\");\n expect(typeof hooks.useCallTool).toBe(\"function\");\n });\n\n it(\"should return an object with useToolInfo hook\", () => {\n const hooks = generateHelpers<TestServer>();\n expect(hooks).toHaveProperty(\"useToolInfo\");\n expect(typeof hooks.useToolInfo).toBe(\"function\");\n });\n});\n"]}
@@ -0,0 +1,7 @@
1
+ import { type SuperJSONResult } from "superjson";
2
+ import type { UnknownObject } from "../types.js";
3
+ export declare function filterViewContext<T extends UnknownObject>(state?: T | null): T | null;
4
+ export declare function injectViewContext<T extends UnknownObject>(newState: T | null): T | null;
5
+ export declare function serializeState(value: UnknownObject): unknown;
6
+ export declare function deserializeState(value: SuperJSONResult): unknown;
7
+ export declare function getInitialState<State extends UnknownObject>(defaultState?: State | (() => State)): State | null;
@@ -0,0 +1,45 @@
1
+ import superjson, {} from "superjson";
2
+ import { getAdaptor } from "../bridges/index.js";
3
+ import { VIEW_CONTEXT_KEY } from "../data-llm.js";
4
+ export function filterViewContext(state) {
5
+ if (state === null || state === undefined) {
6
+ return null;
7
+ }
8
+ const { [VIEW_CONTEXT_KEY]: _, ...filteredState } = state;
9
+ return filteredState;
10
+ }
11
+ export function injectViewContext(newState) {
12
+ if (newState === null) {
13
+ return null;
14
+ }
15
+ const currentState = getAdaptor()
16
+ .getHostContextStore("viewState")
17
+ .getSnapshot();
18
+ if (currentState !== null &&
19
+ currentState !== undefined &&
20
+ VIEW_CONTEXT_KEY in currentState) {
21
+ return {
22
+ ...newState,
23
+ [VIEW_CONTEXT_KEY]: currentState[VIEW_CONTEXT_KEY],
24
+ };
25
+ }
26
+ return newState;
27
+ }
28
+ export function serializeState(value) {
29
+ return superjson.parse(superjson.stringify(value)); // Strips functions
30
+ }
31
+ export function deserializeState(value) {
32
+ return superjson.deserialize(value);
33
+ }
34
+ export function getInitialState(defaultState) {
35
+ const viewState = getAdaptor()
36
+ .getHostContextStore("viewState")
37
+ .getSnapshot();
38
+ if (viewState !== null && viewState !== undefined) {
39
+ return filterViewContext(viewState);
40
+ }
41
+ return typeof defaultState === "function"
42
+ ? defaultState()
43
+ : (defaultState ?? null);
44
+ }
45
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/web/helpers/state.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,EAAE,EAAwB,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGlD,MAAM,UAAU,iBAAiB,CAC/B,KAAgB;IAEhB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,EAAE,GAAG,aAAa,EAAE,GAAG,KAEnD,CAAC;IAEF,OAAO,aAAkB,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,QAAkB;IAElB,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,YAAY,GAAG,UAAU,EAAE;SAC9B,mBAAmB,CAAC,WAAW,CAAC;SAChC,WAAW,EAAmD,CAAC;IAElE,IACE,YAAY,KAAK,IAAI;QACrB,YAAY,KAAK,SAAS;QAC1B,gBAAgB,IAAI,YAAY,EAChC,CAAC;QACD,OAAO;YACL,GAAG,QAAQ;YACX,CAAC,gBAAgB,CAAC,EAAE,YAAY,CAAC,gBAAgB,CAAC;SAC9C,CAAC;IACT,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAoB;IACjD,OAAO,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,mBAAmB;AACzE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAsB;IACrD,OAAO,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,YAAoC;IAEpC,MAAM,SAAS,GAAG,UAAU,EAAE;SAC3B,mBAAmB,CAAC,WAAW,CAAC;SAChC,WAAW,EAAkB,CAAC;IAEjC,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAClD,OAAO,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,OAAO,YAAY,KAAK,UAAU;QACvC,CAAC,CAAC,YAAY,EAAE;QAChB,CAAC,CAAC,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC;AAC7B,CAAC","sourcesContent":["import superjson, { type SuperJSONResult } from \"superjson\";\nimport { getAdaptor } from \"../bridges/index.js\";\nimport { VIEW_CONTEXT_KEY } from \"../data-llm.js\";\nimport type { UnknownObject } from \"../types.js\";\n\nexport function filterViewContext<T extends UnknownObject>(\n state?: T | null,\n): T | null {\n if (state === null || state === undefined) {\n return null;\n }\n\n const { [VIEW_CONTEXT_KEY]: _, ...filteredState } = state as T & {\n [VIEW_CONTEXT_KEY]?: unknown;\n };\n\n return filteredState as T;\n}\n\nexport function injectViewContext<T extends UnknownObject>(\n newState: T | null,\n): T | null {\n if (newState === null) {\n return null;\n }\n\n const currentState = getAdaptor()\n .getHostContextStore(\"viewState\")\n .getSnapshot() as (T & { [VIEW_CONTEXT_KEY]?: unknown }) | null;\n\n if (\n currentState !== null &&\n currentState !== undefined &&\n VIEW_CONTEXT_KEY in currentState\n ) {\n return {\n ...newState,\n [VIEW_CONTEXT_KEY]: currentState[VIEW_CONTEXT_KEY],\n } as T;\n }\n\n return newState;\n}\n\nexport function serializeState(value: UnknownObject) {\n return superjson.parse(superjson.stringify(value)); // Strips functions\n}\n\nexport function deserializeState(value: SuperJSONResult): unknown {\n return superjson.deserialize(value);\n}\n\nexport function getInitialState<State extends UnknownObject>(\n defaultState?: State | (() => State),\n): State | null {\n const viewState = getAdaptor()\n .getHostContextStore(\"viewState\")\n .getSnapshot() as State | null;\n\n if (viewState !== null && viewState !== undefined) {\n return filterViewContext(viewState);\n }\n\n return typeof defaultState === \"function\"\n ? defaultState()\n : (defaultState ?? null);\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,53 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { VIEW_CONTEXT_KEY } from "../data-llm.js";
3
+ import { filterViewContext, serializeState } from "./state.js";
4
+ describe("state helpers", () => {
5
+ describe("filterViewContext", () => {
6
+ it("should return null when state is null", () => {
7
+ expect(filterViewContext(null)).toBe(null);
8
+ });
9
+ it("should return null when state is undefined", () => {
10
+ expect(filterViewContext(undefined)).toBe(null);
11
+ });
12
+ it("should correctly filter VIEW_CONTEXT_KEY and preserve other properties", () => {
13
+ const stateWithContextAndOthers = {
14
+ a: 1,
15
+ b: "two",
16
+ c: { nested: true },
17
+ [VIEW_CONTEXT_KEY]: "context",
18
+ };
19
+ const filteredWithContextAndOthers = filterViewContext(stateWithContextAndOthers);
20
+ expect(filteredWithContextAndOthers).toEqual({
21
+ a: 1,
22
+ b: "two",
23
+ c: { nested: true },
24
+ });
25
+ const stateNoContext = { count: 5, name: "test" };
26
+ const filteredNoContext = filterViewContext(stateNoContext);
27
+ expect(filteredNoContext).toEqual(stateNoContext);
28
+ });
29
+ });
30
+ describe("serializeState", () => {
31
+ it("should serialize plain objects", () => {
32
+ const array = [1, "two", { three: 3 }];
33
+ const date = new Date("2023-01-01T00:00:00Z");
34
+ const object = {
35
+ a: 1,
36
+ b: "test",
37
+ c: true,
38
+ array,
39
+ date,
40
+ function: () => "test",
41
+ };
42
+ const result = serializeState(object);
43
+ expect(result).toEqual({
44
+ a: 1,
45
+ b: "test",
46
+ c: true,
47
+ array: [1, "two", { three: 3 }],
48
+ date: new Date("2023-01-01T00:00:00.000Z"),
49
+ });
50
+ });
51
+ });
52
+ });
53
+ //# sourceMappingURL=state.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.test.js","sourceRoot":"","sources":["../../../src/web/helpers/state.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE/D,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;YAChF,MAAM,yBAAyB,GAAG;gBAChC,CAAC,EAAE,CAAC;gBACJ,CAAC,EAAE,KAAK;gBACR,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;gBACnB,CAAC,gBAAgB,CAAC,EAAE,SAAS;aAC9B,CAAC;YACF,MAAM,4BAA4B,GAAG,iBAAiB,CACpD,yBAAyB,CAC1B,CAAC;YACF,MAAM,CAAC,4BAA4B,CAAC,CAAC,OAAO,CAAC;gBAC3C,CAAC,EAAE,CAAC;gBACJ,CAAC,EAAE,KAAK;gBACR,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;aACpB,CAAC,CAAC;YAEH,MAAM,cAAc,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YAClD,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,cAAc,CAAC,CAAC;YAC5D,MAAM,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;YACxC,MAAM,KAAK,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;YACvC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC,CAAC;YAC9C,MAAM,MAAM,GAAG;gBACb,CAAC,EAAE,CAAC;gBACJ,CAAC,EAAE,MAAM;gBACT,CAAC,EAAE,IAAI;gBACP,KAAK;gBACL,IAAI;gBACJ,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM;aACvB,CAAC;YACF,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;YAEtC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;gBACrB,CAAC,EAAE,CAAC;gBACJ,CAAC,EAAE,MAAM;gBACT,CAAC,EAAE,IAAI;gBACP,KAAK,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;gBAC/B,IAAI,EAAE,IAAI,IAAI,CAAC,0BAA0B,CAAC;aAC3C,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { VIEW_CONTEXT_KEY } from \"../data-llm.js\";\nimport { filterViewContext, serializeState } from \"./state.js\";\n\ndescribe(\"state helpers\", () => {\n describe(\"filterViewContext\", () => {\n it(\"should return null when state is null\", () => {\n expect(filterViewContext(null)).toBe(null);\n });\n\n it(\"should return null when state is undefined\", () => {\n expect(filterViewContext(undefined)).toBe(null);\n });\n\n it(\"should correctly filter VIEW_CONTEXT_KEY and preserve other properties\", () => {\n const stateWithContextAndOthers = {\n a: 1,\n b: \"two\",\n c: { nested: true },\n [VIEW_CONTEXT_KEY]: \"context\",\n };\n const filteredWithContextAndOthers = filterViewContext(\n stateWithContextAndOthers,\n );\n expect(filteredWithContextAndOthers).toEqual({\n a: 1,\n b: \"two\",\n c: { nested: true },\n });\n\n const stateNoContext = { count: 5, name: \"test\" };\n const filteredNoContext = filterViewContext(stateNoContext);\n expect(filteredNoContext).toEqual(stateNoContext);\n });\n });\n\n describe(\"serializeState\", () => {\n it(\"should serialize plain objects\", () => {\n const array = [1, \"two\", { three: 3 }];\n const date = new Date(\"2023-01-01T00:00:00Z\");\n const object = {\n a: 1,\n b: \"test\",\n c: true,\n array,\n date,\n function: () => \"test\",\n };\n const result = serializeState(object);\n\n expect(result).toEqual({\n a: 1,\n b: \"test\",\n c: true,\n array: [1, \"two\", { three: 3 }],\n date: new Date(\"2023-01-01T00:00:00.000Z\"),\n });\n });\n });\n});\n"]}
@@ -0,0 +1,11 @@
1
+ export { type CallToolAsyncFn, type CallToolFn, type CallToolState, type SideEffects, useCallTool, } from "./use-call-tool.js";
2
+ export { useDisplayMode } from "./use-display-mode.js";
3
+ export { useFiles } from "./use-files.js";
4
+ export { type LayoutState, useLayout } from "./use-layout.js";
5
+ export { type OpenExternalFn, useOpenExternal } from "./use-open-external.js";
6
+ export { useRequestModal } from "./use-request-modal.js";
7
+ export { useSendFollowUpMessage } from "./use-send-follow-up-message.js";
8
+ export { useSetOpenInAppUrl } from "./use-set-open-in-app-url.js";
9
+ export { useToolInfo } from "./use-tool-info.js";
10
+ export { type UserState, useUser } from "./use-user.js";
11
+ export { useViewState } from "./use-view-state.js";
@@ -0,0 +1,12 @@
1
+ export { useCallTool, } from "./use-call-tool.js";
2
+ export { useDisplayMode } from "./use-display-mode.js";
3
+ export { useFiles } from "./use-files.js";
4
+ export { useLayout } from "./use-layout.js";
5
+ export { useOpenExternal } from "./use-open-external.js";
6
+ export { useRequestModal } from "./use-request-modal.js";
7
+ export { useSendFollowUpMessage } from "./use-send-follow-up-message.js";
8
+ export { useSetOpenInAppUrl } from "./use-set-open-in-app-url.js";
9
+ export { useToolInfo } from "./use-tool-info.js";
10
+ export { useUser } from "./use-user.js";
11
+ export { useViewState } from "./use-view-state.js";
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/web/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAoB,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAuB,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAkB,OAAO,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC","sourcesContent":["export {\n type CallToolAsyncFn,\n type CallToolFn,\n type CallToolState,\n type SideEffects,\n useCallTool,\n} from \"./use-call-tool.js\";\nexport { useDisplayMode } from \"./use-display-mode.js\";\nexport { useFiles } from \"./use-files.js\";\nexport { type LayoutState, useLayout } from \"./use-layout.js\";\nexport { type OpenExternalFn, useOpenExternal } from \"./use-open-external.js\";\nexport { useRequestModal } from \"./use-request-modal.js\";\nexport { useSendFollowUpMessage } from \"./use-send-follow-up-message.js\";\nexport { useSetOpenInAppUrl } from \"./use-set-open-in-app-url.js\";\nexport { useToolInfo } from \"./use-tool-info.js\";\nexport { type UserState, useUser } from \"./use-user.js\";\nexport { useViewState } from \"./use-view-state.js\";\n"]}
@@ -0,0 +1,16 @@
1
+ import type { McpUiHostContext, McpUiToolResultNotification } from "@modelcontextprotocol/ext-apps";
2
+ export declare class MockResizeObserver {
3
+ observe(): void;
4
+ unobserve(): void;
5
+ disconnect(): void;
6
+ }
7
+ export declare const getMcpAppHostPostMessageMock: (initialContext?: McpUiHostContext) => import("vitest").Mock<(message: {
8
+ method: string;
9
+ id: number;
10
+ }) => void>;
11
+ export declare const fireToolInputNotification: (args: Record<string, unknown>) => void;
12
+ export declare const fireToolResultNotification: (params: {
13
+ content: McpUiToolResultNotification["params"]["content"];
14
+ structuredContent: Record<string, unknown>;
15
+ _meta?: Record<string, unknown>;
16
+ }) => void;
@@ -0,0 +1,64 @@
1
+ import { fireEvent } from "@testing-library/react";
2
+ import { act } from "react";
3
+ import { vi } from "vitest";
4
+ export class MockResizeObserver {
5
+ observe() { }
6
+ unobserve() { }
7
+ disconnect() { }
8
+ }
9
+ const DEFAULT_CONTEXT = {};
10
+ export const getMcpAppHostPostMessageMock = (initialContext = DEFAULT_CONTEXT) => vi.fn((message) => {
11
+ switch (message.method) {
12
+ case "ui/initialize": {
13
+ const result = {
14
+ protocolVersion: "2025-06-18",
15
+ hostInfo: { name: "test-host", version: "1.0.0" },
16
+ hostCapabilities: {},
17
+ hostContext: initialContext,
18
+ };
19
+ act(() => fireEvent(window, new MessageEvent("message", {
20
+ source: window.parent,
21
+ data: {
22
+ jsonrpc: "2.0",
23
+ id: message.id,
24
+ result,
25
+ },
26
+ })));
27
+ break;
28
+ }
29
+ case "ui/update-model-context": {
30
+ act(() => fireEvent(window, new MessageEvent("message", {
31
+ source: window.parent,
32
+ data: {
33
+ jsonrpc: "2.0",
34
+ id: message.id,
35
+ result: {},
36
+ },
37
+ })));
38
+ break;
39
+ }
40
+ }
41
+ });
42
+ export const fireToolInputNotification = (args) => {
43
+ fireEvent(window, new MessageEvent("message", {
44
+ source: window.parent,
45
+ data: {
46
+ jsonrpc: "2.0",
47
+ method: "ui/notifications/tool-input",
48
+ params: {
49
+ arguments: args,
50
+ },
51
+ },
52
+ }));
53
+ };
54
+ export const fireToolResultNotification = (params) => {
55
+ fireEvent(window, new MessageEvent("message", {
56
+ source: window.parent,
57
+ data: {
58
+ jsonrpc: "2.0",
59
+ method: "ui/notifications/tool-result",
60
+ params,
61
+ },
62
+ }));
63
+ };
64
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../src/web/hooks/test/utils.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE5B,MAAM,OAAO,kBAAkB;IAC7B,OAAO,KAAU,CAAC;IAClB,SAAS,KAAU,CAAC;IACpB,UAAU,KAAU,CAAC;CACtB;AAED,MAAM,eAAe,GAAqB,EAAE,CAAC;AAE7C,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAC1C,iBAAmC,eAAe,EAClD,EAAE,CACF,EAAE,CAAC,EAAE,CAAC,CAAC,OAAuC,EAAE,EAAE;IAChD,QAAQ,OAAO,CAAC,MAAM,EAAE,CAAC;QACvB,KAAK,eAAe,CAAC,CAAC,CAAC;YACrB,MAAM,MAAM,GAA0B;gBACpC,eAAe,EAAE,YAAY;gBAC7B,QAAQ,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE;gBACjD,gBAAgB,EAAE,EAAE;gBACpB,WAAW,EAAE,cAAc;aAC5B,CAAC;YACF,GAAG,CAAC,GAAG,EAAE,CACP,SAAS,CACP,MAAM,EACN,IAAI,YAAY,CAIb,SAAS,EAAE;gBACZ,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,IAAI,EAAE;oBACJ,OAAO,EAAE,KAAK;oBACd,EAAE,EAAE,OAAO,CAAC,EAAE;oBACd,MAAM;iBACP;aACF,CAAC,CACH,CACF,CAAC;YACF,MAAM;QACR,CAAC;QACD,KAAK,yBAAyB,CAAC,CAAC,CAAC;YAC/B,GAAG,CAAC,GAAG,EAAE,CACP,SAAS,CACP,MAAM,EACN,IAAI,YAAY,CACd,SAAS,EACT;gBACE,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,IAAI,EAAE;oBACJ,OAAO,EAAE,KAAK;oBACd,EAAE,EAAE,OAAO,CAAC,EAAE;oBACd,MAAM,EAAE,EAAE;iBACX;aACF,CACF,CACF,CACF,CAAC;YACF,MAAM;QACR,CAAC;IACH,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,IAA6B,EAAE,EAAE;IACzE,SAAS,CACP,MAAM,EACN,IAAI,YAAY,CACd,SAAS,EACT;QACE,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,IAAI,EAAE;YACJ,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,6BAA6B;YACrC,MAAM,EAAE;gBACN,SAAS,EAAE,IAAI;aAChB;SACF;KACF,CACF,CACF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,MAI1C,EAAE,EAAE;IACH,SAAS,CACP,MAAM,EACN,IAAI,YAAY,CACd,SAAS,EACT;QACE,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,IAAI,EAAE;YACJ,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,8BAA8B;YACtC,MAAM;SACP;KACF,CACF,CACF,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import type {\n McpUiHostContext,\n McpUiInitializeResult,\n McpUiToolInputNotification,\n McpUiToolResultNotification,\n} from \"@modelcontextprotocol/ext-apps\";\nimport { fireEvent } from \"@testing-library/react\";\nimport { act } from \"react\";\nimport { vi } from \"vitest\";\n\nexport class MockResizeObserver {\n observe(): void {}\n unobserve(): void {}\n disconnect(): void {}\n}\n\nconst DEFAULT_CONTEXT: McpUiHostContext = {};\n\nexport const getMcpAppHostPostMessageMock = (\n initialContext: McpUiHostContext = DEFAULT_CONTEXT,\n) =>\n vi.fn((message: { method: string; id: number }) => {\n switch (message.method) {\n case \"ui/initialize\": {\n const result: McpUiInitializeResult = {\n protocolVersion: \"2025-06-18\",\n hostInfo: { name: \"test-host\", version: \"1.0.0\" },\n hostCapabilities: {},\n hostContext: initialContext,\n };\n act(() =>\n fireEvent(\n window,\n new MessageEvent<{\n jsonrpc: \"2.0\";\n id: number;\n result: McpUiInitializeResult;\n }>(\"message\", {\n source: window.parent,\n data: {\n jsonrpc: \"2.0\",\n id: message.id,\n result,\n },\n }),\n ),\n );\n break;\n }\n case \"ui/update-model-context\": {\n act(() =>\n fireEvent(\n window,\n new MessageEvent<{ jsonrpc: \"2.0\"; id: number; result: unknown }>(\n \"message\",\n {\n source: window.parent,\n data: {\n jsonrpc: \"2.0\",\n id: message.id,\n result: {},\n },\n },\n ),\n ),\n );\n break;\n }\n }\n });\n\nexport const fireToolInputNotification = (args: Record<string, unknown>) => {\n fireEvent(\n window,\n new MessageEvent<McpUiToolInputNotification & { jsonrpc: \"2.0\" }>(\n \"message\",\n {\n source: window.parent,\n data: {\n jsonrpc: \"2.0\",\n method: \"ui/notifications/tool-input\",\n params: {\n arguments: args,\n },\n },\n },\n ),\n );\n};\n\nexport const fireToolResultNotification = (params: {\n content: McpUiToolResultNotification[\"params\"][\"content\"];\n structuredContent: Record<string, unknown>;\n _meta?: Record<string, unknown>;\n}) => {\n fireEvent(\n window,\n new MessageEvent<McpUiToolResultNotification & { jsonrpc: \"2.0\" }>(\n \"message\",\n {\n source: window.parent,\n data: {\n jsonrpc: \"2.0\",\n method: \"ui/notifications/tool-result\",\n params,\n },\n },\n ),\n );\n};\n"]}
@@ -0,0 +1,101 @@
1
+ import { type CallToolArgs, type CallToolResponse } from "../bridges/index.js";
2
+ import type { HasRequiredKeys } from "../types.js";
3
+ type CallToolIdleState = {
4
+ status: "idle";
5
+ isIdle: true;
6
+ isPending: false;
7
+ isSuccess: false;
8
+ isError: false;
9
+ data: undefined;
10
+ error: undefined;
11
+ };
12
+ type CallToolPendingState = {
13
+ status: "pending";
14
+ isIdle: false;
15
+ isPending: true;
16
+ isSuccess: false;
17
+ isError: false;
18
+ data: undefined;
19
+ error: undefined;
20
+ };
21
+ type CallToolSuccessState<TData extends CallToolResponse = CallToolResponse> = {
22
+ status: "success";
23
+ isIdle: false;
24
+ isPending: false;
25
+ isSuccess: true;
26
+ isError: false;
27
+ data: TData;
28
+ error: undefined;
29
+ };
30
+ type CallToolErrorState = {
31
+ status: "error";
32
+ isIdle: false;
33
+ isPending: false;
34
+ isSuccess: false;
35
+ isError: true;
36
+ data: undefined;
37
+ error: unknown;
38
+ };
39
+ export type CallToolState<TData extends CallToolResponse = CallToolResponse> = CallToolIdleState | CallToolPendingState | CallToolSuccessState<TData> | CallToolErrorState;
40
+ export type SideEffects<ToolArgs, ToolResponse> = {
41
+ onSuccess?: (data: ToolResponse, toolArgs: ToolArgs) => void;
42
+ onError?: (error: unknown, toolArgs: ToolArgs) => void;
43
+ onSettled?: (data: ToolResponse | undefined, error: unknown | undefined, toolArgs: ToolArgs) => void;
44
+ };
45
+ type IsArgsOptional<T> = [T] extends [null] ? true : HasRequiredKeys<T> extends false ? true : false;
46
+ export type CallToolFn<TArgs, TResponse> = IsArgsOptional<TArgs> extends true ? {
47
+ (): void;
48
+ (sideEffects: SideEffects<TArgs, TResponse>): void;
49
+ (args: TArgs): void;
50
+ (args: TArgs, sideEffects: SideEffects<TArgs, TResponse>): void;
51
+ } : {
52
+ (args: TArgs): void;
53
+ (args: TArgs, sideEffects: SideEffects<TArgs, TResponse>): void;
54
+ };
55
+ export type CallToolAsyncFn<TArgs, TResponse> = IsArgsOptional<TArgs> extends true ? {
56
+ (): Promise<TResponse>;
57
+ (args: TArgs): Promise<TResponse>;
58
+ } : (args: TArgs) => Promise<TResponse>;
59
+ type ToolResponseSignature = Pick<CallToolResponse, "structuredContent" | "meta">;
60
+ export declare const useCallTool: <ToolArgs extends CallToolArgs = null, ToolResponse extends Partial<ToolResponseSignature> = Record<string, never>>(name: string) => {
61
+ callTool: CallToolFn<ToolArgs, CallToolResponse & ToolResponse>;
62
+ callToolAsync: CallToolAsyncFn<ToolArgs, CallToolResponse & ToolResponse>;
63
+ status: "idle";
64
+ isIdle: true;
65
+ isPending: false;
66
+ isSuccess: false;
67
+ isError: false;
68
+ data: undefined;
69
+ error: undefined;
70
+ } | {
71
+ callTool: CallToolFn<ToolArgs, CallToolResponse & ToolResponse>;
72
+ callToolAsync: CallToolAsyncFn<ToolArgs, CallToolResponse & ToolResponse>;
73
+ status: "pending";
74
+ isIdle: false;
75
+ isPending: true;
76
+ isSuccess: false;
77
+ isError: false;
78
+ data: undefined;
79
+ error: undefined;
80
+ } | {
81
+ callTool: CallToolFn<ToolArgs, CallToolResponse & ToolResponse>;
82
+ callToolAsync: CallToolAsyncFn<ToolArgs, CallToolResponse & ToolResponse>;
83
+ status: "error";
84
+ isIdle: false;
85
+ isPending: false;
86
+ isSuccess: false;
87
+ isError: true;
88
+ data: undefined;
89
+ error: unknown;
90
+ } | {
91
+ callTool: CallToolFn<ToolArgs, CallToolResponse & ToolResponse>;
92
+ callToolAsync: CallToolAsyncFn<ToolArgs, CallToolResponse & ToolResponse>;
93
+ status: "success";
94
+ isIdle: false;
95
+ isPending: false;
96
+ isSuccess: true;
97
+ isError: false;
98
+ data: CallToolResponse & ToolResponse;
99
+ error: undefined;
100
+ };
101
+ export {};
@@ -0,0 +1,68 @@
1
+ import { useRef, useState } from "react";
2
+ import { getAdaptor, } from "../bridges/index.js";
3
+ export const useCallTool = (name) => {
4
+ const [{ status, data, error }, setCallToolState] = useState({ status: "idle", data: undefined, error: undefined });
5
+ const callIdRef = useRef(0);
6
+ const adaptor = getAdaptor();
7
+ const execute = async (toolArgs) => {
8
+ const callId = ++callIdRef.current;
9
+ setCallToolState({ status: "pending", data: undefined, error: undefined });
10
+ try {
11
+ const data = await adaptor.callTool(name, toolArgs);
12
+ if (callId === callIdRef.current) {
13
+ setCallToolState({ status: "success", data, error: undefined });
14
+ }
15
+ return data;
16
+ }
17
+ catch (error) {
18
+ if (callId === callIdRef.current) {
19
+ setCallToolState({ status: "error", data: undefined, error });
20
+ }
21
+ throw error;
22
+ }
23
+ };
24
+ const callToolAsync = ((toolArgs) => {
25
+ if (toolArgs === undefined) {
26
+ return execute(null);
27
+ }
28
+ return execute(toolArgs);
29
+ });
30
+ const callTool = ((firstArg, sideEffects) => {
31
+ let toolArgs;
32
+ if (firstArg &&
33
+ typeof firstArg === "object" &&
34
+ ("onSuccess" in firstArg ||
35
+ "onError" in firstArg ||
36
+ "onSettled" in firstArg)) {
37
+ toolArgs = null; // no toolArgs provided
38
+ sideEffects = firstArg;
39
+ }
40
+ else {
41
+ toolArgs = (firstArg === undefined ? null : firstArg);
42
+ }
43
+ execute(toolArgs)
44
+ .then((data) => {
45
+ sideEffects?.onSuccess?.(data, toolArgs);
46
+ sideEffects?.onSettled?.(data, undefined, toolArgs);
47
+ })
48
+ .catch((error) => {
49
+ sideEffects?.onError?.(error, toolArgs);
50
+ sideEffects?.onSettled?.(undefined, error, toolArgs);
51
+ });
52
+ });
53
+ const callToolState = {
54
+ status,
55
+ data,
56
+ error,
57
+ isIdle: status === "idle",
58
+ isPending: status === "pending",
59
+ isSuccess: status === "success",
60
+ isError: status === "error",
61
+ };
62
+ return {
63
+ ...callToolState,
64
+ callTool,
65
+ callToolAsync,
66
+ };
67
+ };
68
+ //# sourceMappingURL=use-call-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-call-tool.js","sourceRoot":"","sources":["../../../src/web/hooks/use-call-tool.ts"],"names":[],"mappings":"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","sourcesContent":["import { useRef, useState } from \"react\";\n\nimport {\n type CallToolArgs,\n type CallToolResponse,\n getAdaptor,\n} from \"../bridges/index.js\";\nimport type { HasRequiredKeys } from \"../types.js\";\n\ntype CallToolIdleState = {\n status: \"idle\";\n isIdle: true;\n isPending: false;\n isSuccess: false;\n isError: false;\n data: undefined;\n error: undefined;\n};\n\ntype CallToolPendingState = {\n status: \"pending\";\n isIdle: false;\n isPending: true;\n isSuccess: false;\n isError: false;\n data: undefined;\n error: undefined;\n};\n\ntype CallToolSuccessState<TData extends CallToolResponse = CallToolResponse> = {\n status: \"success\";\n isIdle: false;\n isPending: false;\n isSuccess: true;\n isError: false;\n data: TData;\n error: undefined;\n};\n\ntype CallToolErrorState = {\n status: \"error\";\n isIdle: false;\n isPending: false;\n isSuccess: false;\n isError: true;\n data: undefined;\n error: unknown;\n};\n\nexport type CallToolState<TData extends CallToolResponse = CallToolResponse> =\n | CallToolIdleState\n | CallToolPendingState\n | CallToolSuccessState<TData>\n | CallToolErrorState;\n\nexport type SideEffects<ToolArgs, ToolResponse> = {\n onSuccess?: (data: ToolResponse, toolArgs: ToolArgs) => void;\n onError?: (error: unknown, toolArgs: ToolArgs) => void;\n onSettled?: (\n data: ToolResponse | undefined,\n error: unknown | undefined,\n toolArgs: ToolArgs,\n ) => void;\n};\n\ntype IsArgsOptional<T> = [T] extends [null]\n ? true\n : HasRequiredKeys<T> extends false\n ? true\n : false;\n\nexport type CallToolFn<TArgs, TResponse> =\n IsArgsOptional<TArgs> extends true\n ? {\n (): void;\n (sideEffects: SideEffects<TArgs, TResponse>): void;\n (args: TArgs): void;\n (args: TArgs, sideEffects: SideEffects<TArgs, TResponse>): void;\n }\n : {\n (args: TArgs): void;\n (args: TArgs, sideEffects: SideEffects<TArgs, TResponse>): void;\n };\n\nexport type CallToolAsyncFn<TArgs, TResponse> =\n IsArgsOptional<TArgs> extends true\n ? {\n (): Promise<TResponse>;\n (args: TArgs): Promise<TResponse>;\n }\n : (args: TArgs) => Promise<TResponse>;\n\ntype ToolResponseSignature = Pick<\n CallToolResponse,\n \"structuredContent\" | \"meta\"\n>;\n\nexport const useCallTool = <\n ToolArgs extends CallToolArgs = null,\n ToolResponse extends Partial<ToolResponseSignature> = Record<string, never>,\n>(\n name: string,\n) => {\n type CombinedCallToolResponse = CallToolResponse & ToolResponse;\n\n const [{ status, data, error }, setCallToolState] = useState<\n Omit<\n CallToolState<CombinedCallToolResponse>,\n \"isIdle\" | \"isPending\" | \"isSuccess\" | \"isError\"\n >\n >({ status: \"idle\", data: undefined, error: undefined });\n\n const callIdRef = useRef(0);\n const adaptor = getAdaptor();\n\n const execute = async (\n toolArgs: ToolArgs,\n ): Promise<CombinedCallToolResponse> => {\n const callId = ++callIdRef.current;\n setCallToolState({ status: \"pending\", data: undefined, error: undefined });\n\n try {\n const data = await adaptor.callTool<ToolArgs, CombinedCallToolResponse>(\n name,\n toolArgs,\n );\n if (callId === callIdRef.current) {\n setCallToolState({ status: \"success\", data, error: undefined });\n }\n\n return data;\n } catch (error) {\n if (callId === callIdRef.current) {\n setCallToolState({ status: \"error\", data: undefined, error });\n }\n throw error;\n }\n };\n\n const callToolAsync = ((toolArgs?: ToolArgs) => {\n if (toolArgs === undefined) {\n return execute(null as ToolArgs);\n }\n return execute(toolArgs);\n }) as CallToolAsyncFn<ToolArgs, CombinedCallToolResponse>;\n\n const callTool = ((\n firstArg?: ToolArgs | SideEffects<ToolArgs, CombinedCallToolResponse>,\n sideEffects?: SideEffects<ToolArgs, CombinedCallToolResponse>,\n ) => {\n let toolArgs: ToolArgs;\n if (\n firstArg &&\n typeof firstArg === \"object\" &&\n (\"onSuccess\" in firstArg ||\n \"onError\" in firstArg ||\n \"onSettled\" in firstArg)\n ) {\n toolArgs = null as ToolArgs; // no toolArgs provided\n sideEffects = firstArg;\n } else {\n toolArgs = (firstArg === undefined ? null : firstArg) as ToolArgs;\n }\n\n execute(toolArgs)\n .then((data) => {\n sideEffects?.onSuccess?.(data, toolArgs);\n sideEffects?.onSettled?.(data, undefined, toolArgs);\n })\n .catch((error) => {\n sideEffects?.onError?.(error, toolArgs);\n sideEffects?.onSettled?.(undefined, error, toolArgs);\n });\n }) as CallToolFn<ToolArgs, CombinedCallToolResponse>;\n\n const callToolState = {\n status,\n data,\n error,\n isIdle: status === \"idle\",\n isPending: status === \"pending\",\n isSuccess: status === \"success\",\n isError: status === \"error\",\n } as CallToolState<CombinedCallToolResponse>;\n\n return {\n ...callToolState,\n callTool,\n callToolAsync,\n };\n};\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,104 @@
1
+ import { expectTypeOf, test } from "vitest";
2
+ import { useCallTool, } from "./use-call-tool.js";
3
+ test("callTool can be called without args when ToolArgs is null", () => {
4
+ const { callTool, callToolAsync } = useCallTool("test-tool");
5
+ callTool();
6
+ callTool({ onSuccess: () => { } });
7
+ callToolAsync();
8
+ });
9
+ test("callTool requires args when ToolArgs has required properties", () => {
10
+ const { callTool, callToolAsync } = useCallTool("test-tool");
11
+ // @ts-expect-error - query is required
12
+ callTool();
13
+ callTool({ query: "test" });
14
+ callTool({ query: "test" }, { onSuccess: () => { } });
15
+ // @ts-expect-error - query is required
16
+ callToolAsync();
17
+ callToolAsync({ query: "test" });
18
+ });
19
+ test("callTool supports sideEffects with correct types", () => {
20
+ const { callTool } = useCallTool("test-tool");
21
+ callTool({ id: 1 }, {
22
+ onSuccess: (data, args) => {
23
+ expectTypeOf(data.structuredContent.result).toBeString();
24
+ expectTypeOf(args.id).toBeNumber();
25
+ },
26
+ onError: (error, args) => {
27
+ expectTypeOf(error).toBeUnknown();
28
+ expectTypeOf(args.id).toBeNumber();
29
+ },
30
+ onSettled: (data, error, args) => {
31
+ if (data) {
32
+ expectTypeOf(data.structuredContent.result).toBeString();
33
+ }
34
+ expectTypeOf(error).toEqualTypeOf();
35
+ expectTypeOf(args.id).toBeNumber();
36
+ },
37
+ });
38
+ });
39
+ test("callTool allows sideEffects as first arg when ToolArgs is null", () => {
40
+ const { callTool } = useCallTool("test-tool");
41
+ callTool({
42
+ onSuccess: (data) => {
43
+ expectTypeOf(data.structuredContent.value).toBeNumber();
44
+ },
45
+ });
46
+ });
47
+ test("callToolAsync returns correctly typed promise", () => {
48
+ const { callToolAsync } = useCallTool("test-tool");
49
+ const promise = callToolAsync({ name: "test" });
50
+ expectTypeOf(promise).resolves.toHaveProperty("structuredContent");
51
+ expectTypeOf(promise).resolves.toHaveProperty("meta");
52
+ });
53
+ test("state narrowing works correctly with status", () => {
54
+ const result = useCallTool("test-tool");
55
+ if (result.status === "idle") {
56
+ expectTypeOf(result.isIdle).toEqualTypeOf();
57
+ expectTypeOf(result.data).toEqualTypeOf();
58
+ }
59
+ if (result.status === "pending") {
60
+ expectTypeOf(result.isPending).toEqualTypeOf();
61
+ expectTypeOf(result.data).toEqualTypeOf();
62
+ }
63
+ if (result.status === "success") {
64
+ expectTypeOf(result.isSuccess).toEqualTypeOf();
65
+ expectTypeOf(result.data).not.toEqualTypeOf();
66
+ expectTypeOf(result.data.structuredContent.data).toBeString();
67
+ }
68
+ if (result.status === "error") {
69
+ expectTypeOf(result.isError).toEqualTypeOf();
70
+ expectTypeOf(result.error).toBeUnknown();
71
+ }
72
+ });
73
+ test("state narrowing works correctly with boolean flags", () => {
74
+ const result = useCallTool("test-tool");
75
+ if (result.isIdle) {
76
+ expectTypeOf(result.status).toEqualTypeOf();
77
+ }
78
+ if (result.isPending) {
79
+ expectTypeOf(result.status).toEqualTypeOf();
80
+ }
81
+ if (result.isSuccess) {
82
+ expectTypeOf(result.status).toEqualTypeOf();
83
+ expectTypeOf(result.data.structuredContent.items).toBeArray();
84
+ }
85
+ if (result.isError) {
86
+ expectTypeOf(result.status).toEqualTypeOf();
87
+ }
88
+ });
89
+ test("CallToolState type is correctly exported and usable", () => {
90
+ const state = {};
91
+ if (state.status === "success") {
92
+ expectTypeOf(state.data.structuredContent.foo).toBeString();
93
+ }
94
+ });
95
+ test("SideEffects type is correctly exported and usable", () => {
96
+ const sideEffects = {
97
+ onSuccess: (data, args) => {
98
+ expectTypeOf(data.structuredContent.y).toBeString();
99
+ expectTypeOf(args.x).toBeNumber();
100
+ },
101
+ };
102
+ expectTypeOf(sideEffects).toHaveProperty("onSuccess");
103
+ });
104
+ //# sourceMappingURL=use-call-tool.test-d.js.map