I am working on a small Elm-Web-App where I want to use IndexedDB.
I decided to use a ‘ports-only’ solution without Native Modules, but realized that with growing complexity, the number of ports I had to use also grows considerably.
So I was looking for a way to communicate with IndexedDB via ports only, without having to write ports for every database interaction of my app.
The problem here is not so much to send requests to the DB but to direct back the answer to the right place. For me a natural solution was to introduce a new communication layer on top of the Elm <-> JS communication via ports.
For example, one part of the elm app sends a package of the form
{ address : 'todo'
, processBy : 'updateList'
, request : { method : 'GET_ALL'
, storeName : 'todo'
}
}
through the port sendPort
. On the JS-side the request is processed and a result of the form
{ address : 'todo'
, processBy : 'updateList'
, result : '[ ... some objects ... ]'
}
is send back via the answerPort
. Where the address
-field identifies the sub-model that sends the request and the processBy
-field specifies the DbMsg
that should be ‘used’ to process the result.
All sub-models that want to communicate with IndexedDB subscribe to the answerPort
. Based on the address
- field they decide whether they process or discard incoming answers.
If the database request is a modifying operation (add, store, delete) then in addition to the answer a broadcast is send through the broadcastPort
.
I modified Evan’s todo-mvc example to demonstrate the basic idea. You can find the code here and try it out over there. You can read a slightly more detailed explanation in the Readme.MD
My questions are:
- Do you think this approach is at all reasonable or is there maybe a much easier way to achieve what I want?
- Do you think this approach can (reasonably) be applied in big(ger) applications as well?
- What kind of improvements would you suggest?