1 
2 /**
3  A protocol that must be implemented to be a part of module's definition and the module definition itself.
4  */
5 public protocol AnyDefinition {}
6 
7 /**
8  The definition of the module. It is used to define some parameters
9  of the module and what it exports to the JavaScript world.
10  See `ModuleDefinitionBuilder` for more details on how to create it.
11  */
12 public struct ModuleDefinition: AnyDefinition {
13   let name: String?
14   let methods: [String : AnyMethod]
15   let constants: [String : Any?]
16   let eventListeners: [EventListener]
17   let viewManager: ViewManagerDefinition?
18 
19   init(definitions: [AnyDefinition]) {
20     self.name = definitions
21       .compactMap { $0 as? ModuleNameDefinition }
22       .last?
23       .name
24 
25     self.methods = definitions
26       .compactMap { $0 as? AnyMethod }
27       .reduce(into: [String : AnyMethod]()) { dict, method in
28         dict[method.name] = method
29       }
30 
31     self.constants = definitions
32       .compactMap { $0 as? ConstantsDefinition }
33       .reduce(into: [String : Any?]()) { dict, definition in
34         dict.merge(definition.constants) { $1 }
35       }
36 
37     self.eventListeners = definitions.compactMap { $0 as? EventListener }
38 
39     self.viewManager = definitions
40       .compactMap { $0 as? ViewManagerDefinition }
41       .last
42   }
43 }
44 
45 /**
46  Module's name definition. Returned by `name()` in module's definition.
47  */
48 internal struct ModuleNameDefinition: AnyDefinition {
49   let name: String
50 }
51 
52 /**
53  A definition for module's constants. Returned by `constants(() -> SomeType)` in module's definition.
54  */
55 internal struct ConstantsDefinition: AnyDefinition {
56   let constants: [String : Any?]
57 }
58