@@ -23,7 +23,7 @@ function makeMockHost(): MockHost {
2323 } ;
2424}
2525
26- function makeHandle ( opts : { peer ?: JSONObject | undefined ; strict ?: boolean ; peerSchema ?: z . core . $ZodType } ) : {
26+ function makeHandle ( opts : { peer ?: JSONObject | undefined ; peerPresent ?: boolean ; strict ?: boolean ; peerSchema ?: z . core . $ZodType } ) : {
2727 host : MockHost ;
2828 handle : ExtensionHandle < JSONObject , unknown , BaseContext > ;
2929} {
@@ -33,6 +33,7 @@ function makeHandle(opts: { peer?: JSONObject | undefined; strict?: boolean; pee
3333 'io.example/ui' ,
3434 { local : true } ,
3535 ( ) => opts . peer ,
36+ ( ) => opts . peerPresent ?? opts . peer !== undefined ,
3637 ( ) => opts . strict ?? false ,
3738 opts . peerSchema
3839 ) ;
@@ -70,7 +71,14 @@ describe('ExtensionHandle.getPeerSettings', () => {
7071 let peer : JSONObject | undefined ;
7172 const getter = vi . fn ( ( ) => peer ) ;
7273 const host = makeMockHost ( ) as unknown as ExtensionHost < BaseContext > ;
73- const handle = new ExtensionHandle ( host , 'io.example/ui' , { } , getter , ( ) => false ) ;
74+ const handle = new ExtensionHandle (
75+ host ,
76+ 'io.example/ui' ,
77+ { } ,
78+ getter ,
79+ ( ) => true ,
80+ ( ) => false
81+ ) ;
7482
7583 expect ( handle . getPeerSettings ( ) ) . toBeUndefined ( ) ;
7684 peer = { v : 1 } ;
@@ -102,15 +110,15 @@ describe('ExtensionHandle.sendRequest / sendNotification — peer gating', () =>
102110 const Result = z . object ( { ok : z . boolean ( ) } ) ;
103111
104112 test ( 'lax mode (default): sends even when peer did not advertise' , async ( ) => {
105- const { host, handle } = makeHandle ( { peer : undefined , strict : false } ) ;
113+ const { host, handle } = makeHandle ( { peer : undefined , peerPresent : true , strict : false } ) ;
106114 await handle . sendRequest ( 'ui/do' , { x : 1 } , Result ) ;
107115 expect ( host . sendCustomRequest ) . toHaveBeenCalledWith ( 'ui/do' , { x : 1 } , Result , undefined ) ;
108116 await handle . sendNotification ( 'ui/ping' , { } ) ;
109117 expect ( host . sendCustomNotification ) . toHaveBeenCalledWith ( 'ui/ping' , { } , undefined ) ;
110118 } ) ;
111119
112120 test ( 'strict mode: rejects with CapabilityNotSupported when peer did not advertise' , async ( ) => {
113- const { host, handle } = makeHandle ( { peer : undefined , strict : true } ) ;
121+ const { host, handle } = makeHandle ( { peer : undefined , peerPresent : true , strict : true } ) ;
114122 await expect ( handle . sendRequest ( 'ui/do' , { } , Result ) ) . rejects . toSatisfy (
115123 ( e : unknown ) =>
116124 e instanceof SdkError && e . code === SdkErrorCode . CapabilityNotSupported && / i o \. e x a m p l e \/ u i .* u i \/ d o / . test ( e . message )
@@ -138,3 +146,11 @@ describe('ExtensionHandle — id and settings', () => {
138146 expect ( handle . settings ) . toEqual ( { local : true } ) ;
139147 } ) ;
140148} ) ;
149+
150+ describe ( 'ExtensionHandle — pre-connect strict mode defers to NotConnected' , ( ) => {
151+ test ( 'does not throw CapabilityNotSupported before peer capabilities are known' , async ( ) => {
152+ const { host, handle } = makeHandle ( { peer : undefined , peerPresent : false , strict : true } ) ;
153+ await handle . sendRequest ( 'ui/do' , { } , z . object ( { } ) ) ;
154+ expect ( host . sendCustomRequest ) . toHaveBeenCalledOnce ( ) ;
155+ } ) ;
156+ } ) ;
0 commit comments