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 
18   init(definitions: [AnyDefinition]) {
19     self.name = definitions
20       .compactMap { $0 as? ModuleNameDefinition }
21       .last?
22       .name
23 
24     self.methods = definitions
25       .compactMap { $0 as? AnyMethod }
26       .reduce(into: [String : AnyMethod]()) { dict, method in
27         dict[method.name] = method
28       }
29 
30     self.constants = definitions
31       .compactMap { $0 as? ConstantsDefinition }
32       .reduce(into: [String : Any?]()) { dict, definition in
33         dict.merge(definition.constants) { $1 }
34       }
35 
36     self.eventListeners = definitions.compactMap { $0 as? EventListener }
37   }
38 }
39 
40 /**
41  Module's name definition. Returned by `name()` in module's definition.
42  */
43 internal struct ModuleNameDefinition: AnyDefinition {
44   let name: String
45 }
46 
47 /**
48  A definition for module's constants. Returned by `constants(() -> SomeType)` in module's definition.
49  */
50 internal struct ConstantsDefinition: AnyDefinition {
51   let constants: [String : Any?]
52 }
53