• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mobalazs / rotor-framework / 21708335278

05 Feb 2026 10:41AM UTC coverage: 85.915%. Remained the same
21708335278

push

github

mobalazs
refactor: rename ownerDispatcher and ownerDispatcherId to dispatcher and dispatcherId

3 of 4 new or added lines in 2 files covered. (75.0%)

2074 of 2414 relevant lines covered (85.92%)

1.19 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.43
/src/source/base/BaseReducer.bs
1
namespace Rotor
2

3
    ' =====================================================================
4
    ' Reducer (BaseReducer) - Base class for state reducers in the MVI pattern
5
    '
6
    ' Responsibilities:
7
    '   - Computes next state from current state + intent
8
    '   - Applies middleware pipeline for async operations, logging, validation
9
    '   - Provides pure state transformation logic
10
    '   - Integrates with Dispatcher for state updates
11
    '
12
    ' MVI Flow:
13
    '   Intent → Middleware → Reducer → New State → Model → View Update
14
    '
15
    ' Override Points:
16
    '   - reducer(state, intent): Define state transitions
17
    '   - applyMiddlewares(): Return array of middleware functions
18
    '   - middlewares: Set middleware array directly
19
    ' =====================================================================
20
    class Reducer
21

22
        ' =============================================================
23
        ' MEMBER VARIABLES
24
        ' =============================================================
25

26
        middlewares = [] as function[]  ' Middleware function array
27
        port as object                  ' Framework port for async operations
28

29
        ' Dispatcher integration
30
        getDispatcher as function       ' Get dispatcher facade by ID
31
        getState as function            ' Get dispatcher's model state
32
        dispatch as function            ' Dispatch intent to owner dispatcher
33
        dispatchTo as function          ' Dispatch intent to dispatcher by ID
34
        getStateFrom as function        ' Get state from dispatcher by ID
35
        dispatcher as object            ' Owning dispatcher instance
36
        dispatcherId as string          ' Owning dispatcher ID
37

38
        ' Internal
39
        middlewareFnScoped as dynamic   ' Currently executing middleware
40

41
        ' =============================================================
42
        ' CONSTRUCTOR
43
        ' =============================================================
44

45
        ' ---------------------------------------------------------------------
46
        ' Constructor - Initializes reducer with framework integration
47
        '
48
        sub new()
49
            frameworkInstance = GetGlobalAA().rotor_framework_helper.frameworkInstance
1✔
50
            m.port = frameworkInstance.port
1✔
51

52
            ' Inject getDispatcher method
53
            m.getDispatcher = function(dispatcherId as string) as object
1✔
54
                return GetGlobalAA().rotor_framework_helper.frameworkInstance.dispatcherProvider.getFacade(dispatcherId, m)
55
            end function
56

57
            ' Inject dispatch method for dispatching intents
58
            m.dispatch = sub(intent as object)
1✔
59
                m.dispatcher.dispatch(intent)
60
            end sub
61

62
            ' Inject getState method for accessing current state
63
            m.getState = function() as Rotor.Model
1✔
64
                return m.dispatcher.getState()
65
            end function
66

67
            ' Inject dispatchTo method for dispatching intents to other dispatchers
68
            m.dispatchTo = sub(dispatcherId as string, dispatchObject as object)
1✔
69
                dispatcherFacade = m.getDispatcher(dispatcherId)
70
                dispatcherFacade.dispatch(dispatchObject)
71
            end sub
72

73
            ' Inject getStateFrom method for accessing state from other dispatchers
74
            m.getStateFrom = function(dispatcherId as string, mapStateToProps = invalid as dynamic)
1✔
75
                dispatcherFacade = m.getDispatcher(dispatcherId)
76
                return dispatcherFacade.getState(mapStateToProps)
77
            end function
78
        end sub
79

80
        ' =============================================================
81
        ' REDUCER LOGIC
82
        ' =============================================================
83

84
        ' ---------------------------------------------------------------------
85
        ' reducer - Pure function that computes next state
86
        '
87
        ' Override this method to implement custom state transitions based on intent type.
88
        ' Should return a new state object (immutable pattern).
89
        '
90
        ' @param {object} state - Current state
91
        ' @param {Intent} intent - Intent object { type, payload, ... }
92
        ' @return {object} New state
93
        '
94
        ' Example:
95
        '   function reducer(state as object, intent as Intent)
96
        '       if intent.type = "INCREMENT"
97
        '           newState = Rotor.Utils.deepCopy(state)
98
        '           newState.count = state.count + 1
99
        '           return newState
100
        '       end if
101
        '       return state
102
        '   end function
103
        '
104
        public function reducer(state as object, intent as Intent)
105
            return state
1✔
106
        end function
107

108
        ' =============================================================
109
        ' MIDDLEWARE
110
        ' =============================================================
111

112
        ' ---------------------------------------------------------------------
113
        ' applyMiddlewares - Returns middleware function array
114
        '
115
        ' Override to implement middleware logic for:
116
        '   - Async operations (API calls, timers)
117
        '   - Logging and debugging
118
        '   - Intent validation
119
        '   - Intent transformation
120
        '
121
        ' @return {function[]} Array of middleware functions
122
        '
123
        ' Middleware signature:
124
        '   function(intent as Intent, state as object) as Dynamic
125
        '   - Return intent to continue pipeline
126
        '   - Return modified intent to transform
127
        '   - Return invalid to cancel reducer execution
128
        '
129
        public function applyMiddlewares() as function[]
130
            return [] as function[]
1✔
131
        end function
132

133
        ' =============================================================
134
        ' REDUCE PIPELINE
135
        ' =============================================================
136

137
        ' ---------------------------------------------------------------------
138
        ' reduce - Executes middleware pipeline and reducer
139
        '
140
        ' Process flow:
141
        '   1. Validate intent payload
142
        '   2. Execute middleware pipeline
143
        '   3. If intent survives, execute reducer
144
        '   4. Return new state or invalid
145
        '
146
        ' @param {object} state - Current state
147
        ' @param {Intent} intent - Intent to process
148
        ' @return {object} New state, or invalid if cancelled
149
        '
150
        function reduce(state as object, intent as Intent) as object
151
            if intent?.payload <> invalid and intent.payload.Count() > 1 and intent.payload = invalid
2✔
152
                throw "[WARNING] Intent payload is invalid."
153
            end if
154

155
            ' Execute middleware pipeline
156
            middlewares = m.applyMiddlewares()
1✔
157
            mwIndex = 0
1✔
158
            mwCount = middlewares.Count()
1✔
159
            while intent <> invalid and mwIndex < mwCount
1✔
160
                middlewareFnScoped = middlewares[mwIndex]
1✔
161
                m.middlewareFnScoped = middlewareFnScoped
1✔
162
                intent = m.middlewareFnScoped(intent, state)
1✔
163
                mwIndex++
1✔
164
            end while
165
            m.middlewareFnScoped = invalid
1✔
166

167
            ' Middleware cancelled intent
168
            if intent = invalid then return invalid
2✔
169

170
            ' Execute reducer
171
            newState = m.reducer(state, intent)
1✔
172

173
            return newState
1✔
174
        end function
175

176
        ' =============================================================
177
        ' ASYNC TRANSFER SUPPORT
178
        ' =============================================================
179

180
        ' ---------------------------------------------------------------------
181
        ' registerAsyncTransfer - Registers a roUrlTransfer with the framework
182
        '
183
        ' Helper method to simplify async HTTP request tracking. Call this after
184
        ' creating a roUrlTransfer but BEFORE calling AsyncGetToString() or other
185
        ' async methods.
186
        '
187
        ' @param {object} transfer - The roUrlTransfer object
188
        ' @param {object} context - Optional data to receive in asyncReducerCallback
189
        '
190
        ' Example:
191
        '   transfer = CreateObject("roUrlTransfer")
192
        '   transfer.SetUrl("https://api.example.com/data")
193
        '   transfer.SetMessagePort(m.port)
194
        '   m.registerAsyncTransfer(transfer, { userId: 123 })
195
        '   transfer.AsyncGetToString()
196
        '
197
        sub registerAsyncTransfer(transfer as object, context = invalid as dynamic)
198
            frameworkInstance = GetGlobalAA().rotor_framework_helper.frameworkInstance
1✔
199
            transferId = transfer.GetIdentity().ToStr()
1✔
200

201
            ' Only call if the method exists (task thread only)
202
            if Rotor.Utils.isFunction(frameworkInstance?.registerAsyncTransfer)
2✔
NEW
203
                frameworkInstance.registerAsyncTransfer(transferId, m.dispatcherId, context)
×
204
            end if
205
        end sub
206

207
        ' =============================================================
208
        ' ASYNC CALLBACK
209
        ' =============================================================
210

211
        ' ---------------------------------------------------------------------
212
        ' asyncReducerCallback - Callback for async middleware operations
213
        '
214
        ' @param {object} msg - Message from async operation
215
        '
216
        sub asyncReducerCallback(msg as roUrlEvent, context as dynamic)
217
            ' Override in subclass to handle async responses
218
        end sub
219

220
        ' =============================================================
221
        ' CLEANUP
222
        ' =============================================================
223

224
        ' ---------------------------------------------------------------------
225
        ' destroy - Cleans up reducer references
226
        '
227
        sub destroy()
228
            m.dispatcher = invalid
1✔
229
            m.port = invalid
1✔
230
        end sub
231

232
    end class
233

234
end namespace
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc