1 // Copyright 2022-present 650 Industries. All rights reserved.
2 
3 // FIXME: Calling module's functions needs solid refactoring to not reference the module holder.
4 // Instead, it should be possible to directly call the function instance from here. (added by @tsapeta)
5 
6 /**
7  Creates a block that is executed when the module's async function is called.
8  */
9 internal func createAsyncFunctionBlock(holder: ModuleHolder, name functionName: String) -> JSAsyncFunctionBlock {
10   let moduleName = holder.name
11   return { [weak holder, moduleName] args, resolve, reject in
12     guard let holder = holder else {
13       let exception = ModuleUnavailableException(moduleName)
14       reject(exception.code, exception.description, exception)
15       return
16     }
17     holder.call(function: functionName, args: args) { result, error in
18       if let error = error {
19         reject(error.code, error.description, error)
20       } else {
21         resolve(result)
22       }
23     }
24   }
25 }
26 
27 /**
28  Creates a block that is executed when the module's sync function is called.
29  */
30 internal func createSyncFunctionBlock(holder: ModuleHolder, name functionName: String) -> JSSyncFunctionBlock {
31   return { [weak holder] args in
32     guard let holder = holder else {
33       return nil
34     }
35     return holder.callSync(function: functionName, args: args)
36   }
37 }
38 
39 private class ModuleUnavailableException: GenericException<String> {
40   override var reason: String {
41     "Module '\(param)' is no longer available"
42   }
43 }
44