UNPKG

3.73 kBtext/coffeescriptView Raw
1inmemoryRemote = require 'eventric-remote-inmemory'
2
3GlobalContext = require './global_context'
4Remote = require './remote'
5Projection = require './projection'
6Context = require './context'
7InmemoryStore = require 'eventric-store-inmemory'
8uuidGenerator = require './uuid_generator'
9logger = require './logger'
10remoteContextHash = {}
11
12class 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 # TODO: Test
30 setStore: (StoreClass, storeOptions = {}) ->
31 @_storeDefinition =
32 Class: StoreClass
33 options: storeOptions
34
35
36 # TODO: Test
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 # TODO: Reconsider/Remove when adding EventStore
56 initializeGlobalProjections: ->
57 Promise.all @_globalProjectionObjects.map (projectionObject) =>
58 @_projectionService.initializeInstance projectionObject, {}
59
60
61 # TODO: Reconsider/Remove when adding EventStore
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
139module.exports = new Eventric