@@ -174,6 +174,7 @@ const FUNCTION_METHOD_PREFIX = channelMethod('function', '')
174174 */
175175export function createLocalFunctionRegistry ( codec : InPageChannelSerialization ) : {
176176 register : ( definition : InPageFunctionDefinitionAny ) => void
177+ registerInternal : ( method : string , handler : ( ...args : unknown [ ] ) => unknown ) => void
177178 on : ( name : string , listener : ( ...args : unknown [ ] ) => void ) => ( ) => void
178179 resolve : ( name : string ) => ( ( ...args : unknown [ ] ) => unknown ) | undefined
179180} {
@@ -183,6 +184,12 @@ export function createLocalFunctionRegistry(codec: InPageChannelSerialization):
183184 register ( definition ) {
184185 definitions . set ( channelMethod ( definition . type , definition . name ) , definition )
185186 } ,
187+ // The shared-state layer keys its handlers by their own fully-qualified
188+ // wire methods (`devframe:in-page:page-state:*`, the panel-state events),
189+ // so they register verbatim rather than through `channelMethod`.
190+ registerInternal ( method , handler ) {
191+ definitions . set ( method , { name : method , handler } )
192+ } ,
186193 on ( name , listener ) {
187194 const key = channelMethod ( 'event' , name )
188195 let registered = listeners . get ( key )
@@ -200,14 +207,8 @@ export function createLocalFunctionRegistry(codec: InPageChannelSerialization):
200207 resolve ( name ) {
201208 const definition = definitions . get ( name )
202209 const registered = listeners . get ( name )
203- if ( ! definition && ! registered ?. size ) {
204- if ( name . startsWith ( FUNCTION_METHOD_PREFIX ) ) {
205- return ( ) => {
206- throw diagnostics . DF0077 ( { name : name . slice ( FUNCTION_METHOD_PREFIX . length ) } )
207- }
208- }
210+ if ( ! definition && ! registered ?. size )
209211 return undefined
210- }
211212 return async ( ...rawArgs : unknown [ ] ) => {
212213 const args = codec . deserialize ? rawArgs . map ( codec . deserialize ) : rawArgs
213214 if ( definition ?. jsonSerializable )
@@ -227,6 +228,31 @@ export function createLocalFunctionRegistry(codec: InPageChannelSerialization):
227228 }
228229}
229230
231+ type LocalHandler = ( ...args : unknown [ ] ) => unknown
232+
233+ /**
234+ * Consult each registry in order and, only once none owns the name, fall back
235+ * to the coded "not registered" error for a `function:` call (events stay
236+ * silent). The fallback lives here, after every registry, so chaining a
237+ * state registry ahead of the user registry never masks a real handler.
238+ */
239+ export function resolveLocalHandler (
240+ name : string ,
241+ registries : ( ( name : string ) => LocalHandler | undefined ) [ ] ,
242+ ) : LocalHandler | undefined {
243+ for ( const registry of registries ) {
244+ const handler = registry ( name )
245+ if ( handler )
246+ return handler
247+ }
248+ if ( name . startsWith ( FUNCTION_METHOD_PREFIX ) ) {
249+ return ( ) => {
250+ throw diagnostics . DF0077 ( { name : name . slice ( FUNCTION_METHOD_PREFIX . length ) } )
251+ }
252+ }
253+ return undefined
254+ }
255+
230256type RemoteFunctions = Record < string , ( ...args : any [ ] ) => any >
231257
232258export interface AttachChannelPortOptions {
0 commit comments