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