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

mobalazs / rotor-framework / 19980247662

06 Dec 2025 12:52AM UTC coverage: 85.611% (-0.6%) from 86.229%
19980247662

Pull #10

github

web-flow
Merge f2448421e into 2846dc2eb
Pull Request #10: Feat/url transfer support

2 of 15 new or added lines in 2 files covered. (13.33%)

2 existing lines in 2 files now uncovered.

1773 of 2071 relevant lines covered (85.61%)

1.16 hits per line

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

88.0
/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
        ownerDispatcher as object       ' Owning dispatcher instance
34
        ownerDispatcherId as string     ' Owning dispatcher ID
35

36
        ' Internal
37
        middlewareFnScoped as dynamic   ' Currently executing middleware
38

39
        ' =============================================================
40
        ' CONSTRUCTOR
41
        ' =============================================================
42

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

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

55
            ' Inject dispatch method for dispatching intents
56
            m.dispatch = sub(intent as object)
1✔
57
                m.ownerDispatcher.dispatch(intent)
58
            end sub
59

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

66
        ' =============================================================
67
        ' REDUCER LOGIC
68
        ' =============================================================
69

70
        ' ---------------------------------------------------------------------
71
        ' reducer - Pure function that computes next state
72
        '
73
        ' Override this method to implement custom state transitions based on intent type.
74
        ' Should return a new state object (immutable pattern).
75
        '
76
        ' @param {object} state - Current state
77
        ' @param {Intent} intent - Intent object { type, payload, ... }
78
        ' @return {object} New state
79
        '
80
        ' Example:
81
        '   function reducer(state as object, intent as Intent)
82
        '       if intent.type = "INCREMENT"
83
        '           newState = Rotor.Utils.deepCopy(state)
84
        '           newState.count = state.count + 1
85
        '           return newState
86
        '       end if
87
        '       return state
88
        '   end function
89
        '
90
        public function reducer(state as object, intent as Intent)
91
            return state
1✔
92
        end function
93

94
        ' =============================================================
95
        ' MIDDLEWARE
96
        ' =============================================================
97

98
        ' ---------------------------------------------------------------------
99
        ' applyMiddlewares - Returns middleware function array
100
        '
101
        ' Override to implement middleware logic for:
102
        '   - Async operations (API calls, timers)
103
        '   - Logging and debugging
104
        '   - Intent validation
105
        '   - Intent transformation
106
        '
107
        ' @return {function[]} Array of middleware functions
108
        '
109
        ' Middleware signature:
110
        '   function(intent as Intent, state as object) as Dynamic
111
        '   - Return intent to continue pipeline
112
        '   - Return modified intent to transform
113
        '   - Return invalid to cancel reducer execution
114
        '
115
        public function applyMiddlewares() as function[]
116
            return [] as function[]
1✔
117
        end function
118

119
        ' =============================================================
120
        ' REDUCE PIPELINE
121
        ' =============================================================
122

123
        ' ---------------------------------------------------------------------
124
        ' reduce - Executes middleware pipeline and reducer
125
        '
126
        ' Process flow:
127
        '   1. Validate intent payload
128
        '   2. Execute middleware pipeline
129
        '   3. If intent survives, execute reducer
130
        '   4. Return new state or invalid
131
        '
132
        ' @param {object} state - Current state
133
        ' @param {Intent} intent - Intent to process
134
        ' @return {object} New state, or invalid if cancelled
135
        '
136
        function reduce(state as object, intent as Intent) as object
137
            if intent?.payload <> invalid and intent.payload.Count() > 1 and intent.payload = invalid
2✔
138
                throw "[WARNING] Intent payload is invalid."
139
            end if
140

141
            ' Execute middleware pipeline
142
            middlewares = m.applyMiddlewares()
1✔
143
            mwIndex = 0
1✔
144
            mwCount = middlewares.Count()
1✔
145
            while intent <> invalid and mwIndex < mwCount
1✔
146
                middlewareFnScoped = middlewares[mwIndex]
1✔
147
                m.middlewareFnScoped = middlewareFnScoped
1✔
148
                intent = m.middlewareFnScoped(intent, state)
1✔
149
                mwIndex++
1✔
150
            end while
151
            m.middlewareFnScoped = invalid
1✔
152

153
            ' Middleware cancelled intent
154
            if intent = invalid then return invalid
2✔
155

156
            ' Execute reducer
157
            newState = m.reducer(state, intent)
1✔
158

159
            return newState
1✔
160
        end function
161

162
        ' =============================================================
163
        ' ASYNC TRANSFER SUPPORT
164
        ' =============================================================
165

166
        ' ---------------------------------------------------------------------
167
        ' registerAsyncTransfer - Registers a roUrlTransfer with the framework
168
        '
169
        ' Helper method to simplify async HTTP request tracking. Call this after
170
        ' creating a roUrlTransfer but BEFORE calling AsyncGetToString() or other
171
        ' async methods.
172
        '
173
        ' @param {object} transfer - The roUrlTransfer object
174
        ' @param {object} context - Optional data to receive in asyncReducerCallback
175
        '
176
        ' Example:
177
        '   transfer = CreateObject("roUrlTransfer")
178
        '   transfer.SetUrl("https://api.example.com/data")
179
        '   transfer.SetMessagePort(m.port)
180
        '   m.registerAsyncTransfer(transfer, { userId: 123 })
181
        '   transfer.AsyncGetToString()
182
        '
183
        sub registerAsyncTransfer(transfer as object, context = invalid as dynamic)
NEW
184
            frameworkInstance = GetGlobalAA().rotor_framework_helper.frameworkInstance
×
NEW
185
            transferId = transfer.GetIdentity().ToStr()
×
186

NEW
187
            frameworkInstance.registerAsyncTransfer(transferId, m.ownerDispatcherId, context)
×
188
        end sub
189

190
        ' =============================================================
191
        ' ASYNC CALLBACK
192
        ' =============================================================
193

194
        ' ---------------------------------------------------------------------
195
        ' asyncReducerCallback - Callback for async middleware operations
196
        '
197
        ' @param {object} msg - Message from async operation
198
        '
199
        sub asyncReducerCallback(msg)
200
            ' Override in subclass to handle async responses
201
        end sub
202

203
        ' =============================================================
204
        ' CLEANUP
205
        ' =============================================================
206

207
        ' ---------------------------------------------------------------------
208
        ' destroy - Cleans up reducer references
209
        '
210
        sub destroy()
211
            m.ownerDispatcher = invalid
1✔
212
            m.port = invalid
1✔
213
        end sub
214

215
    end class
216

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

© 2026 Coveralls, Inc