1 | inmemoryRemote = require 'eventric-remote-inmemory'
|
2 |
|
3 | GlobalContext = require './global_context'
|
4 | Remote = require './remote'
|
5 | Projection = require './projection'
|
6 | Context = require './context'
|
7 | InmemoryStore = require 'eventric-store-inmemory'
|
8 | uuidGenerator = require './uuid_generator'
|
9 | logger = require './logger'
|
10 | remoteContextHash = {}
|
11 |
|
12 | class Eventric
|
13 |
|
14 | constructor: ->
|
15 | @_contexts = {}
|
16 | @_params = {}
|
17 | @_domainEventHandlers = {}
|
18 | @_domainEventHandlersAll = []
|
19 | @_storeDefinition = null
|
20 | @_remoteEndpoints = []
|
21 | @_globalProjectionObjects = []
|
22 |
|
23 | @_globalContext = new GlobalContext
|
24 | @_projectionService = new Projection @_globalContext
|
25 | @addRemoteEndpoint inmemoryRemote.endpoint
|
26 | @setStore InmemoryStore, {}
|
27 |
|
28 |
|
29 |
|
30 | setStore: (StoreClass, storeOptions = {}) ->
|
31 | @_storeDefinition =
|
32 | Class: StoreClass
|
33 | options: storeOptions
|
34 |
|
35 |
|
36 |
|
37 | getStoreDefinition: ->
|
38 | @_storeDefinition
|
39 |
|
40 |
|
41 | context: (name) ->
|
42 | if !name
|
43 | throw new Error 'Contexts must have a name'
|
44 |
|
45 | context = new Context name
|
46 |
|
47 | context.subscribeToAllDomainEvents (domainEvent) =>
|
48 | @_delegateDomainEventToRemoteEndpoints domainEvent
|
49 |
|
50 | @_contexts[name] = context
|
51 |
|
52 | context
|
53 |
|
54 |
|
55 |
|
56 | initializeGlobalProjections: ->
|
57 | Promise.all @_globalProjectionObjects.map (projectionObject) =>
|
58 | @_projectionService.initializeInstance projectionObject, {}
|
59 |
|
60 |
|
61 |
|
62 | addGlobalProjection: (projectionObject) ->
|
63 | @_globalProjectionObjects.push projectionObject
|
64 |
|
65 |
|
66 | getRegisteredContextNames: ->
|
67 | Object.keys @_contexts
|
68 |
|
69 |
|
70 | setDefaultRemoteClient: (remoteClient) ->
|
71 | @_defaultRemoteClient = remoteClient
|
72 |
|
73 |
|
74 | remoteContext: (contextName) ->
|
75 | if !contextName
|
76 | throw new Error 'Missing context name'
|
77 |
|
78 | return remoteContextHash[contextName] if remoteContextHash[contextName]
|
79 |
|
80 | remote = remoteContextHash[contextName] = new Remote contextName
|
81 |
|
82 | if @_defaultRemoteClient
|
83 | remote.setClient @_defaultRemoteClient
|
84 |
|
85 | return remote
|
86 |
|
87 |
|
88 | addRemoteEndpoint: (remoteEndpoint) ->
|
89 | @_remoteEndpoints.push remoteEndpoint
|
90 | remoteEndpoint.setRPCHandler @_handleRemoteRPCRequest
|
91 |
|
92 |
|
93 | generateUuid: ->
|
94 | uuidGenerator.generateUuid()
|
95 |
|
96 |
|
97 | setLogLevel: (logLevel) ->
|
98 | logger.setLogLevel logLevel
|
99 |
|
100 |
|
101 | _handleRemoteRPCRequest: (request, callback) =>
|
102 | context = @_contexts[request.contextName]
|
103 | if not context
|
104 | error = new Error "Tried to handle Remote RPC with not registered context #{request.contextName}"
|
105 | logger.error error.stack
|
106 | callback error, null
|
107 | return
|
108 |
|
109 | if Remote.ALLOWED_RPC_OPERATIONS.indexOf(request.functionName) is -1
|
110 | error = new Error "RPC operation '#{request.functionName}' not allowed"
|
111 | logger.error error.stack
|
112 | callback error, null
|
113 | return
|
114 |
|
115 | if request.functionName not of context
|
116 | error = new Error "Remote RPC function #{request.functionName} not found on Context #{request.contextName}"
|
117 | logger.error error.stack
|
118 | callback error, null
|
119 | return
|
120 |
|
121 | context[request.functionName] request.args...
|
122 | .then (result) ->
|
123 | callback null, result
|
124 | .catch (error) ->
|
125 | callback error
|
126 |
|
127 |
|
128 | _delegateDomainEventToRemoteEndpoints: (domainEvent) ->
|
129 | Promise.all @_remoteEndpoints.map (remoteEndpoint) ->
|
130 | publishPromise = Promise.resolve().then ->
|
131 | remoteEndpoint.publish domainEvent.context, domainEvent.name, domainEvent
|
132 | if domainEvent.aggregate
|
133 | publishPromise = publishPromise.then ->
|
134 | remoteEndpoint.publish domainEvent.context, domainEvent.name, domainEvent.aggregate.id, domainEvent
|
135 |
|
136 | return publishPromise
|
137 |
|
138 |
|
139 | module.exports = new Eventric
|