@@ -11,6 +11,7 @@ import {
1111 deserializeError ,
1212 MainToWorkerMessage ,
1313 MessageBroker ,
14+ RequestMessage ,
1415 ResponseMessage ,
1516 ITCInterface ,
1617 serializeError ,
@@ -265,29 +266,94 @@ 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+ ( message : RequestMessage ) => ResponseMessage [ "data" ] [ "response" ]
287+ >
288+ > = {
289+ invokeRemoteJSObjectBody : ( message ) => {
290+ const invocationContext = message . data . request
291+ . parameters [ 0 ] as pointer ;
292+ const hasError = this . exports . swjs_invoke_remote_jsobject_body (
293+ invocationContext ,
294+ ) ;
295+ return {
296+ ok : true ,
297+ value : {
298+ object : hasError ,
299+ sendingContext : message . data . context ,
300+ transfer : [ ] ,
301+ } ,
302+ } ;
303+ } ,
304+ } ;
305+
306+ const defaultResponseHandler = ( message : ResponseMessage ) => {
307+ if ( message . data . response . ok ) {
308+ const object = this . memory . retain (
309+ message . data . response . value . object ,
310+ ) ;
311+ this . exports . swjs_receive_response (
312+ object ,
313+ message . data . context ,
314+ ) ;
315+ } else {
316+ const error = deserializeError ( message . data . response . error ) ;
317+ const errorObject = this . memory . retain ( error ) ;
318+ this . exports . swjs_receive_error (
319+ errorObject ,
320+ message . data . context ,
321+ ) ;
322+ }
323+ } ;
324+
325+ const responseHandlers : Partial <
326+ Record < ITCMethodName , ( message : ResponseMessage ) => void >
327+ > = {
328+ invokeRemoteJSObjectBody : ( _message ) => {
329+ // Swift continuation is resumed on the owner thread.
330+ } ,
331+ } ;
332+
268333 const newBroker = new MessageBroker ( this . tid ?? - 1 , threadChannel , {
269334 onRequest : ( message ) => {
270335 let returnValue : ResponseMessage [ "data" ] [ "response" ] ;
271336 try {
272- // @ts -ignore
273- const result = itcInterface [
274- message . data . request . method
275- ] ( ...message . data . request . parameters ) ;
276- returnValue = { ok : true , value : result } ;
337+ const method = message . data . request . method ;
338+ const handler = requestHandlers [ method ] ?? defaultRequestHandler ;
339+ returnValue = handler ( message ) ;
277340 } catch ( error ) {
278341 returnValue = {
279342 ok : false ,
280343 error : serializeError ( error ) ,
281344 } ;
282345 }
346+
283347 const responseMessage : ResponseMessage = {
284348 type : "response" ,
285349 data : {
286350 sourceTid : message . data . sourceTid ,
287351 context : message . data . context ,
352+ requestMethod : message . data . request . method ,
288353 response : returnValue ,
289354 } ,
290355 } ;
356+
291357 try {
292358 newBroker . reply ( responseMessage ) ;
293359 } catch ( error ) {
@@ -303,24 +369,9 @@ export class SwiftRuntime {
303369 }
304370 } ,
305371 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- }
372+ const method = message . data . requestMethod ;
373+ const handler = responseHandlers [ method ] ?? defaultResponseHandler ;
374+ handler ( message ) ;
324375 } ,
325376 } ) ;
326377 broker = newBroker ;
@@ -934,6 +985,29 @@ export class SwiftRuntime {
934985 } ,
935986 } ) ;
936987 } ,
988+ swjs_request_remote_jsobject_body : (
989+ object_source_tid : number ,
990+ invocation_context : pointer ,
991+ ) => {
992+ if ( ! this . options . threadChannel ) {
993+ throw new Error (
994+ "threadChannel is not set in options given to SwiftRuntime. Please set it to request remote JSObject access." ,
995+ ) ;
996+ }
997+ const broker = getMessageBroker ( this . options . threadChannel ) ;
998+ broker . request ( {
999+ type : "request" ,
1000+ data : {
1001+ sourceTid : this . tid ?? MAIN_THREAD_TID ,
1002+ targetTid : object_source_tid ,
1003+ context : invocation_context ,
1004+ request : {
1005+ method : "invokeRemoteJSObjectBody" ,
1006+ parameters : [ invocation_context ] ,
1007+ } ,
1008+ } ,
1009+ } ) ;
1010+ } ,
9371011 } ;
9381012 }
9391013
0 commit comments