Add addEventListener/removeEventListener with DOM-model on* semantics#573
Add addEventListener/removeEventListener with DOM-model on* semantics#573
Conversation
📖 Docs Preview Deployed
Includes drafts and future-dated posts. All pages served with |
@modelcontextprotocol/ext-apps
@modelcontextprotocol/server-basic-preact
@modelcontextprotocol/server-basic-react
@modelcontextprotocol/server-basic-solid
@modelcontextprotocol/server-basic-svelte
@modelcontextprotocol/server-basic-vanillajs
@modelcontextprotocol/server-basic-vue
@modelcontextprotocol/server-budget-allocator
@modelcontextprotocol/server-cohort-heatmap
@modelcontextprotocol/server-customer-segmentation
@modelcontextprotocol/server-debug
@modelcontextprotocol/server-map
@modelcontextprotocol/server-pdf
@modelcontextprotocol/server-scenario-modeler
@modelcontextprotocol/server-shadertoy
@modelcontextprotocol/server-sheet-music
@modelcontextprotocol/server-system-monitor
@modelcontextprotocol/server-threejs
@modelcontextprotocol/server-transcript
@modelcontextprotocol/server-video-resource
@modelcontextprotocol/server-wiki-explorer
commit: |
…ntListener Fixes #551 (useHostStyles broken: fonts clobber theme/CSS variables) Fixes #225 (user onhostcontextchanged and SDK hooks mutually exclusive) The on* setters now follow the DOM event model: - Replace semantics (like el.onclick) with getters - Coexist with addEventListener/removeEventListener listeners - Both channels fire on dispatch: on* handler then listeners Introduces ProtocolWithEvents base class between Protocol and App/AppBridge. Each notification event gets a slot with two independent channels (singular on* handler + addEventListener listener array). useHostStyles hooks now use addEventListener with proper cleanup, so they compose correctly with user on* handlers. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
f121180 to
a1ebc1b
Compare
|
love it! I think we should keep |
If we keep the old handler, would it be possible to add a console warning when it's being overwritten and that it's deprecated? |
| params: McpUiResourceTeardownRequest["params"], | ||
| extra: RequestHandlerExtra, | ||
| ) => McpUiResourceTeardownResult | Promise<McpUiResourceTeardownResult>) | ||
| | undefined, |
There was a problem hiding this comment.
Any issues with this being undefined? Wouldn't if (callback) skip on undefined?
| | (( | ||
| params: ListToolsRequest["params"], | ||
| extra: RequestHandlerExtra, | ||
| ) => Promise<ListToolsResult>) |
There was a problem hiding this comment.
Previous implementations like this would break, right?
app.onlisttools = () => ({ tools: ["foo"]})Do we need to document this?
Adds DOM-model event semantics to
on*setters and introducesaddEventListener/removeEventListenerfor multi-listener support. Theon*setters now have replace semantics (likeel.onclick) with getters, and coexist withaddEventListenerlisteners — both fire on dispatch.useHostStylesbroken: fonts handler clobbers theme/CSS variables)onhostcontextchangedand SDK hooks are mutually exclusive)getHostContext()robust (context merge now happens unconditionally inonEventDispatch, not in a replaceable setter wrapper)How it works
New
ProtocolWithEventsbase class betweenProtocolandApp/AppBridge. Each notification event gets a slot with two independent channels:on*setteraddEventListenerapp.ontoolinput = undefinedremoveEventListener(event, fn)app.ontoolinputreturns handlerDispatch order:
onEventDispatch()(side-effects) →on*handler →addEventListenerlisteners.Other changes
on*properties on bothAppandAppBridgereplaceRequestHandlerfor request-handleron*setters (replace semantics, no double-set throw)useHostStyleVariablesanduseHostFontsnow useaddEventListenerwith proper cleanupTest plan
on*replace semantics, coexistence withaddEventListener, getters, clearingsetRequestHandler/setNotificationHandler🤖 Generated with Claude Code