8.0 Platform abstraction layer
Monterey is ran in a NodeJS environment when it is started by Electron. This allows Monterey to use all goodies of NodeJS: fs.readFile
, os.getPlatform()
and everything else. We quickly discovered that using these functions directly caused the Karma test runner to fail, as Karma runs Monterey in a browser environment and not in a NodeJS environment. There also were plans to create a simulator, which would simulate certain actions taken by Monterey. This lead to the idea to create a platform abstraction layer for Monterey, inspired by Aurelia's platform abstraction layer.
Monterey's PAL consists of two parts: monterey-pal and monterey-pal-electron. Monterey-pal-electron
can be seen as an implementation of the monterey-pal
interface.
Monterey uses monterey-pal
, but it does not care what the implementation of monterey-pal
is. If monterey calls FS.readFile('foo.txt')
, then it expects the content of the 'foo.text' file to be returned, but it does not care how this file is read
By default Monterey uses monterey-pal-electron
which implements all functions of monterey-pal
. In index.html the following code registers monterey-pal-electron:
<script>
System.import('monterey-pal')
.then(() => System.import('monterey-pal-electron').then(pal => pal.initialize())) <---
.then(() => System.import('aurelia-bootstrapper'));
</script>
8.1 What happens here?
Lets use the FS
(filesystem) class of monterey-pal
as an example. Here monterey-pal has a readFile
function, which throws an error mentioning that the function has not been implemented. If monterey-pal-electron would not be initialized, and you would run the following code:
import {FS} from 'monterey-pal';
FS.readFile();
Then you would get the error Not implemented
.
When monterey starts up, it initializes monterey-pal-electron. The job of monterey-pal-electron is to override all functions in monterey-pal
with the actual implementation of these functions.
For example, the readFile function of monterey-pal:
readFile(filePath) {
throw new Error('Not implemented');
}
needs to be overriden with the readFile function of monterey-pal-electron:
async readFile(filePath) {
return new Promise((resolve, reject) => {
fs.readFile(filePath, 'utf8', function(err, data) {
if (err) {
reject(err);
}
resolve(data);
});
});
}
This takes place in the initialize function of monterey-pal-electron
, which is called from index.html
.
8.2 Working on the pal
First make sure that the node_modules in the monterey-pal
and monterey-pal-electron
directories were installed.
Assuming that the steps in chapter 1.1 and chapter 1.2 were followed, running node run link
from the monterey-framework
directory will jspm link
monterey-pal and monterey-pal-electronto monterey. After every change in monterey-pal and monterey-pal-electron, the
node run link` command must be executed again for the changes to show up in Monterey.
When satisfied with the changes to monterey-pal / monterey-pal-electron, use the following steps to release this change, something which is necessary for other monterey developers to get these changes.
- In the package.json of both monterey-pal and monterey-pal-electron, bump the version number
- Push the changes of monterey-pal and monterey-pal-electron to github.
- Create a release on github for both monterey-pal and monterey-pal-electron
- run
node run unlink
from the monterey-framework directory to fetch monterey-pal and monterey-pal-electron from github, and update the versions in config.js. - Push the changes of monterey to github