feat(widget-light): reactivity, events, and improved defaults#669
feat(widget-light): reactivity, events, and improved defaults#669
Conversation
…ved compatibility
…t integration and features
| type SendFn = (msg: HostMessage) => void | ||
| type Handler = (data: unknown) => void | ||
|
|
||
| const listeners = new Map<string, Set<Handler>>() |
There was a problem hiding this comment.
listeners is a module-level mutable Map that persists across imports; avoid storing request/user-specific handlers globally or scope them per session.
Details
✨ AI Reasoning
The change introduced module-level mutable state: a Map of listeners, a Map of refCounts, and a module-scoped send function reference. Module-level mutable variables persist for the lifetime of the process and can therefore retain per-request or per-user data between requests. This can lead to data leakage or race conditions when the module is used in long-lived server processes or reused across different iframe sessions. Consider scoping these data structures per-session/instance or clearly documenting them as intentionally shared.
🔧 How do I fix it?
Avoid storing request-specific data in module-level variables. Use request-scoped variables or explicitly mark shared caches as intentional.
Reply @AikidoSec feedback: [FEEDBACK] to get better review comments in the future.
Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info
Which Linear task is linked to this PR?
N/A
Why was it implemented this way?
This PR builds on the initial widget-light foundation (#664) to add config reactivity, a typed event system, multi-ecosystem handler improvements, and developer experience polish.
Config reactivity & events
CONFIG_UPDATEmessage)WidgetLightEventBussingleton with ref-counted subscriptions — guest forwards subscribed events viaWIDGET_EVENTmessagesuseWidgetLightEvents()hook returning{ on, off }emitter with full TypeScript supportWidgetLightEvents) mirroring the full widget's event systemProtocol & iframe bridge improvements
WIDGET_EVENT_SUBSCRIBE/UNSUBSCRIBE,RESIZE,CONNECT_WALLET_REQUESTmessagesBaseIframeProviderbase class shared across all chain providers (EVM, Solana, Bitcoin, Sui)WidgetEventsBridgecomponent in widget-embedded to forward widget events to the hostGuestBridgeimprovements for reliable handshake and event forwardingwidgetLightConnector— inlined connector info updates, removed separateupdateConnectorInfofunctionDefault URL & DX improvements
srcandiframeOriginprops are now optional on<LiFiWidgetLight>— defaults tohttps://widget.li.fiwithiframeOriginauto-derived fromsrcvianew URL(src).originDEFAULT_WIDGET_URLconstant for hook-only consumersWIDGET_URL/WIDGET_ORIGINboilerplateonConnectprop — widget sendsCONNECT_WALLET_REQUESTinstead of opening internal wallet menuDocs & tooling
widget-embedded/README.mdintegration guide (quick start, multi-ecosystem setup, events, props table, FAQ)CLAUDE.mdwith repo conventions, commands, and architecture overviewVisual showcase (Screenshots or Videos)
No visual changes — infrastructure, protocol, and API improvements.
Checklist before requesting a review
🤖 Generated with Claude Code