Closed lukebarnard1 closed 6 years ago
I've realised that redux apps will want to store non-matrix state in the same store under a different state key. This is still compatible with all of the above, but we leave the store creation to the app.
So this library will only expose:
To be specified:
mrw.*
state in response to dispatched actionsThe events will be as actions fairly simply:
{
"type": "mrw.wrapped_event",
"emittedType": emittedType,
"emittedArgs": emittedArgs,
}
where:
type
- the name-spaced action type (mrw = matrix-redux-wrap
);emittedType
- the name of the event emitted (e.g. "Room.name");emittedArgs
- the arguments emitted.The advantages of this are:
and the disadvantages are:
The API is exposed in a series of many Promise-returning functions that do some asynchronous work. These can easily be encapsulated in Asynchronous Action Creators, which are essentially actions that take the form:
(dispatch) => { ... }
and when dispatched on the Redux store (which has the redux-thunk
middleware applied), the function will be called with a reference to the dispatch
function of the store, allowing it to be called asynchronously.
The three async actions that are:
These will be encapsulated in actions that resemble:
{
"type": "mrw.wrapped_api.pending",
"method": "login",
"pendingState": pendingState,
"id": "48ghdkh9"
}
where:
type
is the name-spaced action type (mrw = matrix-redux-wrap
);method
is the name of the function that will be called on the MatrixClient instance;pendingState
is the a useful way to pass state known at the point of calling the API;id
the request ID that links this pending action with a potential future "failure" or "success".{
"type": "mrw.wrapped_api.success",
"method": "login",
"result": { ... },
"id": "48ghdkh9"
}
where:
type
is the name-spaced action type (mrw = matrix-redux-wrap
);method
is the name of the function called on the MatrixClient instance;result
is the value that the returned promise resolves to;id
the request ID that links this success with the previously emitted "pending" action.{
"type": "mrw.wrapped_api.failure",
"method": "login",
"error": new Error(':slight_frown:'),
"id": "48ghdkh9"
}
where:
type
is the name-spaced action type (mrw = matrix-redux-wrap
);method
is the name of the function called on the MatrixClient instance;error
is the thrown value;id
the request ID that links this success with the previously emitted "pending" action.Closing due to progress being made, I shall make a big checklist of things that need to be done next 🙂
Architecture
To wrap the js-sdk, each event emitted by it will be handled by the store as an action. Each action will update the store state accordingly with a set of reducers.
Many actions will reduce state in a similar fashion; updating the stored values for matrix state. All state will be copied from the js-sdk to prevent bugs from state changing without an action having been fired. This has many advantages but one major disadvantage is memory footprint. The plan is to replace this wrapper with a proper matrix-redux-store that has its own logic for handling the /sync response, effectively replacing stateful parts of the js-sdk but leaving HTTP API wrappers intact.
Apps wanting multi-account support for their app should simply create multiple stores; the accounts should be effectively sandboxed.
Glossary
Store structure