1 /**
2  Extends all modules with the functions used to build a module definition.
3  Unfortunately they need to be scoped here, but hopefully this proposal
4  https://github.com/apple/swift-evolution/blob/main/proposals/0289-result-builders.md#builder-scoped-name-lookup
5  will be implemented in the future.
6  */
7 extension AnyModule {
8   /**
9    Sets the name of the module that is exported to the JavaScript world.
10    */
11   public func name(_ name: String) -> AnyDefinition {
12     return ModuleNameDefinition(name: name)
13   }
14 
15   /**
16    Definition function setting the module's constants to export.
17    */
18   public func constants(_ closure: () -> [String : Any?]) -> AnyDefinition {
19     return ConstantsDefinition(constants: closure())
20   }
21 
22   /**
23    Factory function for methods without arguments.
24    */
25   public func method<R>(
26     _ name: String,
27     queue: DispatchQueue? = nil,
28     _ closure: @escaping () -> R
29   ) -> AnyMethod {
30     return ConcreteMethod(
31       name,
32       argTypes: [],
33       queue: queue,
34       closure
35     )
36   }
37 
38   /**
39    Factory function for methods with one argument.
40    */
41   public func method<R, A0: AnyMethodArgument>(
42     _ name: String,
43     queue: DispatchQueue? = nil,
44     _ closure: @escaping (A0) -> R
45   ) -> AnyMethod {
46     return ConcreteMethod(
47       name,
48       argTypes: [AnyArgumentType(A0.self)],
49       queue: queue,
50       closure
51     )
52   }
53 
54   /**
55    Factory function for methods with 2 arguments.
56    */
57   public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument>(
58     _ name: String,
59     queue: DispatchQueue? = nil,
60     _ closure: @escaping (A0, A1) -> R
61   ) -> AnyMethod {
62     return ConcreteMethod(
63       name,
64       argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self)],
65       queue: queue,
66       closure
67     )
68   }
69 
70   /**
71    Factory function for methods with 3 arguments.
72    */
73   public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument>(
74     _ name: String,
75     queue: DispatchQueue? = nil,
76     _ closure: @escaping (A0, A1, A2) -> R
77   ) -> AnyMethod {
78     return ConcreteMethod(
79       name,
80       argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self)],
81       queue: queue,
82       closure
83     )
84   }
85 
86   /**
87    Factory function for methods with 4 arguments.
88    */
89   public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument>(
90     _ name: String,
91     queue: DispatchQueue? = nil,
92     _ closure: @escaping (A0, A1, A2, A3) -> R
93   ) -> AnyMethod {
94     return ConcreteMethod(
95       name,
96       argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self)],
97       queue: queue,
98       closure
99     )
100   }
101 
102   /**
103    Factory function for methods with 5 arguments.
104    */
105   public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument, A4: AnyMethodArgument>(
106     _ name: String,
107     queue: DispatchQueue? = nil,
108     _ closure: @escaping (A0, A1, A2, A3, A4) -> R
109   ) -> AnyMethod {
110     return ConcreteMethod(
111       name,
112       argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self), AnyArgumentType(A4.self)],
113       queue: queue,
114       closure
115     )
116   }
117 
118   /**
119    Factory function for methods with 6 arguments.
120    */
121   public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument, A4: AnyMethodArgument, A5: AnyMethodArgument>(
122     _ name: String,
123     queue: DispatchQueue? = nil,
124     _ closure: @escaping (A0, A1, A2, A3, A4, A5) -> R
125   ) -> AnyMethod {
126     return ConcreteMethod(
127       name,
128       argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self), AnyArgumentType(A4.self), AnyArgumentType(A5.self)],
129       queue: queue,
130       closure
131     )
132   }
133 
134   /**
135    Factory function for methods with 7 arguments.
136    */
137   public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument, A4: AnyMethodArgument, A5: AnyMethodArgument, A6: AnyMethodArgument>(
138     _ name: String,
139     queue: DispatchQueue? = nil,
140     _ closure: @escaping (A0, A1, A2, A3, A4, A5, A6) -> R
141   ) -> AnyMethod {
142     return ConcreteMethod(
143       name,
144       argTypes: [AnyArgumentType(A0.self), AnyArgumentType(A1.self), AnyArgumentType(A2.self), AnyArgumentType(A3.self), AnyArgumentType(A4.self), AnyArgumentType(A5.self), AnyArgumentType(A6.self)],
145       queue: queue,
146       closure
147     )
148   }
149 
150   /**
151    Factory function for methods with 8 arguments.
152    */
153   public func method<R, A0: AnyMethodArgument, A1: AnyMethodArgument, A2: AnyMethodArgument, A3: AnyMethodArgument, A4: AnyMethodArgument, A5: AnyMethodArgument, A6: AnyMethodArgument, A7: AnyMethodArgument>(
154     _ name: String,
155     queue: DispatchQueue? = nil,
156     _ closure: @escaping (A0, A1, A2, A3, A4, A5, A6, A7) -> R
157   ) -> AnyMethod {
158     return ConcreteMethod(
159       name,
160       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)],
161       queue: queue,
162       closure
163     )
164   }
165 
166   /**
167    Creates module's lifecycle listener that is called right after module initialization.
168    */
169   public func onCreate(_ closure: @escaping () -> Void) -> AnyDefinition {
170     return EventListener(.moduleCreate, closure)
171   }
172 
173   /**
174    Creates module's lifecycle listener that is called when the module is about to be deallocated.
175    */
176   public func onDestroy(_ closure: @escaping () -> Void) -> AnyDefinition {
177     return EventListener(.moduleDestroy, closure)
178   }
179 
180   /**
181    Creates module's lifecycle listener that is called when the app context owning the module is about to be deallocated.
182    */
183   public func onAppContextDestroys(_ closure: @escaping () -> Void) -> AnyDefinition {
184     return EventListener(.appContextDestroys, closure)
185   }
186 
187   /**
188    Creates a listener that is called when the app is about to enter the foreground mode.
189    */
190   public func onAppEntersForeground(_ closure: @escaping () -> Void) -> AnyDefinition {
191     return EventListener(.appEntersForeground, closure)
192   }
193 
194   /**
195    Creates a listener that is called when the app becomes active again.
196    */
197   public func onAppBecomesActive(_ closure: @escaping () -> Void) -> AnyDefinition {
198     return EventListener(.appBecomesActive, closure)
199   }
200 
201   /**
202    Creates a listener that is called when the app enters the background mode.
203    */
204   public func onAppEntersBackground(_ closure: @escaping () -> Void) -> AnyDefinition {
205     return EventListener(.appEntersBackground, closure)
206   }
207 }
208