1 import UIKit
2 
3 /**
4  Extends all modules with the functions used to build a module definition.
5  Unfortunately they need to be scoped here, but hopefully this proposal
6  https://github.com/apple/swift-evolution/blob/main/proposals/0289-result-builders.md#builder-scoped-name-lookup
7  will be implemented in the future.
8  */
9 extension AnyModule {
10   // MARK: - Module name
11 
12   /**
13    Sets the name of the module that is exported to the JavaScript world.
14    */
15   public static func name(_ name: String) -> AnyDefinition {
16     return ModuleNameDefinition(name: name)
17   }
18 
19   // MARK: - Constants
20 
21   /**
22    Definition function setting the module's constants to export.
23    */
24   public static func constants(_ closure: () -> [String : Any?]) -> AnyDefinition {
25     return ConstantsDefinition(constants: closure())
26   }
27 
28   // MARK: - Methods
29 
30   /**
31    Factory function for methods without the module instance and arguments.
32    */
33   public static func method<R>(
34     _ name: String,
35     _ closure: @escaping () -> R
36   ) -> AnyMethod {
37     return ConcreteMethod(
38       name,
39       argTypes: [],
40       closure,
41       detached: true
42     )
43   }
44 
45   /**
46    Factory function for methods without arguments.
47    */
48   public static func method<R>(
49     _ name: String,
50     _ closure: @escaping (Self) -> R
51   ) -> AnyMethod {
52     return ConcreteMethod(
53       name,
54       argTypes: [],
55       closure
56     )
57   }
58 
59   /**
60    Factory function for methods with one argument.
61    */
62   public static func method<R, A0: AnyMethodArgument>(
63     _ name: String,
64     _ closure: @escaping (Self, A0) -> R
65   ) -> AnyMethod {
66     return ConcreteMethod(
67       name,
68       argTypes: [AnyArgumentType(A0.self)],
69       closure
70     )
71   }
72 
73   /**
74    Factory function for methods with 2 arguments.
75    */
76   public static func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument>(
77     _ name: String,
78     _ closure: @escaping (Self, A0, A1) -> R
79   ) -> AnyMethod {
80     return ConcreteMethod(
81       name,
82       argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self)],
83       closure
84     )
85   }
86 
87   /**
88    Factory function for methods with 3 arguments.
89    */
90   public static func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument>(
91     _ name: String,
92     _ closure: @escaping (Self, A0, A1, A2) -> R
93   ) -> AnyMethod {
94     return ConcreteMethod(
95       name,
96       argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self)],
97       closure
98     )
99   }
100 
101   /**
102    Factory function for methods with 4 arguments.
103    */
104   public static func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument>(
105     _ name: String,
106     _ closure: @escaping (Self, A0, A1, A2, A3) -> R
107   ) -> AnyMethod {
108     return ConcreteMethod(
109       name,
110       argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self)],
111       closure
112     )
113   }
114 
115   /**
116    Factory function for methods with 5 arguments.
117    */
118   public static func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument, A4: AnyMethodArgument>(
119     _ name: String,
120     _ closure: @escaping (Self, A0, A1, A2, A3, A4) -> R
121   ) -> AnyMethod {
122     return ConcreteMethod(
123       name,
124       argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self), AnyArgumentType(A4.self)],
125       closure
126     )
127   }
128 
129   /**
130    Factory function for methods with 6 arguments.
131    */
132   public static func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument, A4: AnyMethodArgument, A5: AnyMethodArgument>(
133     _ name: String,
134     _ closure: @escaping (Self, A0, A1, A2, A3, A4, A5) -> R
135   ) -> AnyMethod {
136     return ConcreteMethod(
137       name,
138       argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self), AnyArgumentType(A4.self), AnyArgumentType(A5.self)],
139       closure
140     )
141   }
142 
143   /**
144    Factory function for methods with 7 arguments.
145    */
146   public static func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument, A4: AnyMethodArgument, A5: AnyMethodArgument, A6: AnyMethodArgument>(
147     _ name: String,
148     _ closure: @escaping (Self, A0, A1, A2, A3, A4, A5, A6) -> R
149   ) -> AnyMethod {
150     return ConcreteMethod(
151       name,
152       argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self), AnyArgumentType(A4.self), AnyArgumentType(A5.self), AnyArgumentType(A6.self)],
153       closure
154     )
155   }
156 
157   /**
158    Factory function for methods with 8 arguments.
159    */
160   public static func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument, A4: AnyMethodArgument, A5: AnyMethodArgument, A6: AnyMethodArgument, A7: AnyMethodArgument>(
161     _ name: String,
162     _ closure: @escaping (Self, A0, A1, A2, A3, A4, A5, A6, A7) -> R
163   ) -> AnyMethod {
164     return ConcreteMethod(
165       name,
166       argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self), AnyArgumentType(A4.self), AnyArgumentType(A5.self), AnyArgumentType(A6.self), AnyArgumentType(A7.self)],
167       closure
168     )
169   }
170 
171   // MARK: - `onCreate`
172 
173   /**
174    Creates module's lifecycle listener that is called right after module initialization.
175    */
176   public static func onCreate(_ closure: @escaping () -> Void) -> AnyDefinition {
177     return EventListener(.moduleCreate, closure)
178   }
179 
180   /**
181    Creates module's lifecycle listener that is called right after module initialization.
182    */
183   public static func onCreate(_ closure: @escaping (Self) -> Void) -> AnyDefinition {
184     return EventListener(.moduleCreate, closure)
185   }
186 
187   // MARK: - `onDestroy`
188 
189   /**
190    Creates module's lifecycle listener that is called when the module is about to be deallocated.
191    */
192   public static func onDestroy(_ closure: @escaping () -> Void) -> AnyDefinition {
193     return EventListener(.moduleDestroy, closure)
194   }
195 
196   /**
197    Creates module's lifecycle listener that is called when the module is about to be deallocated.
198    */
199   public static func onDestroy(_ closure: @escaping (Self) -> Void) -> AnyDefinition {
200     return EventListener(.moduleDestroy, closure)
201   }
202 
203   // MARK: - `onAppContextDestroys`
204 
205   /**
206    Creates module's lifecycle listener that is called when the app context owning the module is about to be deallocated.
207    */
208   public static func onAppContextDestroys(_ closure: @escaping () -> Void) -> AnyDefinition {
209     return EventListener(.appContextDestroys, closure)
210   }
211 
212   /**
213    Creates module's lifecycle listener that is called when the app context owning the module is about to be deallocated.
214    */
215   public static func onAppContextDestroys(_ closure: @escaping (Self) -> Void) -> AnyDefinition {
216     return EventListener(.appContextDestroys, closure)
217   }
218 
219   // MARK: - `onAppEntersForeground`
220 
221   /**
222    Creates a listener that is called when the app is about to enter the foreground mode.
223    */
224   public static func onAppEntersForeground(_ closure: @escaping () -> Void) -> AnyDefinition {
225     return EventListener(.appEntersForeground, closure)
226   }
227 
228   /**
229    Creates a listener that is called when the app is about to enter the foreground mode.
230    */
231   public static func onAppEntersForeground(_ closure: @escaping (Self) -> Void) -> AnyDefinition {
232     return EventListener(.appEntersForeground, closure)
233   }
234 
235   // MARK: - `onAppBecomesActive`
236 
237   /**
238    Creates a listener that is called when the app becomes active again.
239    */
240   public static func onAppBecomesActive(_ closure: @escaping () -> Void) -> AnyDefinition {
241     return EventListener(.appBecomesActive, closure)
242   }
243 
244   /**
245    Creates a listener that is called when the app becomes active again.
246    */
247   public static func onAppBecomesActive(_ closure: @escaping (Self) -> Void) -> AnyDefinition {
248     return EventListener(.appBecomesActive, closure)
249   }
250 
251   // MARK: - `onAppEntersBackground`
252 
253   /**
254    Creates a listener that is called when the app enters the background mode.
255    */
256   public static func onAppEntersBackground(_ closure: @escaping () -> Void) -> AnyDefinition {
257     return EventListener(.appEntersBackground, closure)
258   }
259 
260   /**
261    Creates a listener that is called when the app enters the background mode.
262    */
263   public static func onAppEntersBackground(_ closure: @escaping (Self) -> Void) -> AnyDefinition {
264     return EventListener(.appEntersBackground, closure)
265   }
266 
267   // MARK: - View Manager
268 
269   /**
270    Creates the view manager definition that scopes other view-related definitions.
271    */
272   public static func viewManager(@ViewManagerDefinitionBuilder _ closure: @escaping () -> ViewManagerDefinition) -> AnyDefinition {
273     return closure()
274   }
275 
276   /**
277    Defines the factory creating a native view when the module is used as a view.
278    */
279   public static func view(_ closure: @escaping () -> UIView) -> AnyDefinition {
280     return ViewFactory(closure)
281   }
282 
283   /**
284    Creates a view prop that defines its name and setter.
285    */
286   public static func prop<ViewType: UIView, PropType>(_ name: String, _ setter: @escaping (ViewType, PropType) -> Void) -> AnyDefinition {
287     return ConcreteViewProp(name, setter)
288   }
289 }
290