@@ -11,6 +11,7 @@ import {
1111 deserializeError ,
1212 MainToWorkerMessage ,
1313 MessageBroker ,
14+ RequestMessage ,
1415 ResponseMessage ,
1516 ITCInterface ,
1617 serializeError ,
@@ -265,29 +266,98 @@ export class SwiftRuntime {
265266 const getMessageBroker = ( threadChannel : SwiftRuntimeThreadChannel ) => {
266267 if ( broker ) return broker ;
267268 const itcInterface = new ITCInterface ( this . memory ) ;
269+ type ITCMethodName = keyof ITCInterface ;
270+
271+ const defaultRequestHandler = (
272+ message : RequestMessage ,
273+ ) : ResponseMessage [ "data" ] [ "response" ] => {
274+ const request = message . data . request ;
275+ // @ts -ignore dynamic dispatch by method name
276+ const result = itcInterface [ request . method ] . apply (
277+ itcInterface ,
278+ request . parameters as any [ ] ,
279+ ) ;
280+ return { ok : true , value : result } ;
281+ } ;
282+
283+ const requestHandlers : Partial <
284+ Record <
285+ ITCMethodName ,
286+ (
287+ message : RequestMessage ,
288+ ) => ResponseMessage [ "data" ] [ "response" ]
289+ >
290+ > = {
291+ invokeRemoteJSObjectBody : ( message ) => {
292+ const invocationContext = message . data . request
293+ . parameters [ 0 ] as pointer ;
294+ const hasError =
295+ this . exports . swjs_invoke_remote_jsobject_body (
296+ invocationContext ,
297+ ) ;
298+ return {
299+ ok : true ,
300+ value : {
301+ object : hasError ,
302+ sendingContext : message . data . context ,
303+ transfer : [ ] ,
304+ } ,
305+ } ;
306+ } ,
307+ } ;
308+
309+ const defaultResponseHandler = ( message : ResponseMessage ) => {
310+ if ( message . data . response . ok ) {
311+ const object = this . memory . retain (
312+ message . data . response . value . object ,
313+ ) ;
314+ this . exports . swjs_receive_response (
315+ object ,
316+ message . data . context ,
317+ ) ;
318+ } else {
319+ const error = deserializeError ( message . data . response . error ) ;
320+ const errorObject = this . memory . retain ( error ) ;
321+ this . exports . swjs_receive_error (
322+ errorObject ,
323+ message . data . context ,
324+ ) ;
325+ }
326+ } ;
327+
328+ const responseHandlers : Partial <
329+ Record < ITCMethodName , ( message : ResponseMessage ) => void >
330+ > = {
331+ invokeRemoteJSObjectBody : ( _message ) => {
332+ // Swift continuation is resumed on the owner thread.
333+ } ,
334+ } ;
335+
268336 const newBroker = new MessageBroker ( this . tid ?? - 1 , threadChannel , {
269337 onRequest : ( message ) => {
270338 let returnValue : ResponseMessage [ "data" ] [ "response" ] ;
271339 try {
272- // @ts -ignore
273- const result = itcInterface [
274- message . data . request . method
275- ] ( ...message . data . request . parameters ) ;
276- returnValue = { ok : true , value : result } ;
340+ const method = message . data . request . method ;
341+ const handler =
342+ requestHandlers [ method ] ?? defaultRequestHandler ;
343+ returnValue = handler ( message ) ;
277344 } catch ( error ) {
278345 returnValue = {
279346 ok : false ,
280347 error : serializeError ( error ) ,
281348 } ;
282349 }
350+
283351 const responseMessage : ResponseMessage = {
284352 type : "response" ,
285353 data : {
286354 sourceTid : message . data . sourceTid ,
287355 context : message . data . context ,
356+ requestMethod : message . data . request . method ,
288357 response : returnValue ,
289358 } ,
290359 } ;
360+
291361 try {
292362 newBroker . reply ( responseMessage ) ;
293363 } catch ( error ) {
@@ -303,24 +373,10 @@ export class SwiftRuntime {
303373 }
304374 } ,
305375 onResponse : ( message ) => {
306- if ( message . data . response . ok ) {
307- const object = this . memory . retain (
308- message . data . response . value . object ,
309- ) ;
310- this . exports . swjs_receive_response (
311- object ,
312- message . data . context ,
313- ) ;
314- } else {
315- const error = deserializeError (
316- message . data . response . error ,
317- ) ;
318- const errorObject = this . memory . retain ( error ) ;
319- this . exports . swjs_receive_error (
320- errorObject ,
321- message . data . context ,
322- ) ;
323- }
376+ const method = message . data . requestMethod ;
377+ const handler =
378+ responseHandlers [ method ] ?? defaultResponseHandler ;
379+ handler ( message ) ;
324380 } ,
325381 } ) ;
326382 broker = newBroker ;
@@ -934,6 +990,29 @@ export class SwiftRuntime {
934990 } ,
935991 } ) ;
936992 } ,
993+ swjs_request_remote_jsobject_body : (
994+ object_source_tid : number ,
995+ invocation_context : pointer ,
996+ ) => {
997+ if ( ! this . options . threadChannel ) {
998+ throw new Error (
999+ "threadChannel is not set in options given to SwiftRuntime. Please set it to request remote JSObject access." ,
1000+ ) ;
1001+ }
1002+ const broker = getMessageBroker ( this . options . threadChannel ) ;
1003+ broker . request ( {
1004+ type : "request" ,
1005+ data : {
1006+ sourceTid : this . tid ?? MAIN_THREAD_TID ,
1007+ targetTid : object_source_tid ,
1008+ context : invocation_context ,
1009+ request : {
1010+ method : "invokeRemoteJSObjectBody" ,
1011+ parameters : [ invocation_context ] ,
1012+ } ,
1013+ } ,
1014+ } ) ;
1015+ } ,
9371016 } ;
9381017 }
9391018
0 commit comments