diff --git a/Framework/docs/tutorial/public/app.js b/Framework/docs/tutorial/public/app.js
new file mode 100644
index 000000000..addbed804
--- /dev/null
+++ b/Framework/docs/tutorial/public/app.js
@@ -0,0 +1,26 @@
+/**
+ * @license
+ * Copyright 2019-2020 CERN and copyright holders of ALICE O2.
+ * See http://alice-o2.web.cern.ch/copyright for details of the copyright holders.
+ * All rights not expressly granted are reserved.
+ *
+ * This software is distributed under the terms of the GNU General Public
+ * License v3 (GPL Version 3), copied verbatim in the file "COPYING".
+ *
+ * In applying this license CERN does not waive the privileges and immunities
+ * granted to it by virtue of its status as an Intergovernmental Organization
+ * or submit itself to any jurisdiction.
+*/
+
+// Import MVC
+import {mount} from '/js/src/index.js';
+import view from './view.js';
+import Model from './Model.js';
+
+// Start application
+const model = new Model();
+const debug = true; // shows when redraw is done
+mount(document.body, view, model, debug);
+
+// Expose model to interact with it the browser's console
+window.model = model;
diff --git a/Framework/docs/tutorial/public/index.html b/Framework/docs/tutorial/public/index.html
index d8508d2c1..e52fe1ff2 100644
--- a/Framework/docs/tutorial/public/index.html
+++ b/Framework/docs/tutorial/public/index.html
@@ -1,26 +1,9 @@
Tutorial - Time server
-
-
+
-
+
diff --git a/Framework/docs/tutorial/public/session.js b/Framework/docs/tutorial/public/session.js
new file mode 100644
index 000000000..8bde304a2
--- /dev/null
+++ b/Framework/docs/tutorial/public/session.js
@@ -0,0 +1,16 @@
+/**
+ * @license
+ * Copyright 2019-2020 CERN and copyright holders of ALICE O2.
+ * See http://alice-o2.web.cern.ch/copyright for details of the copyright holders.
+ * All rights not expressly granted are reserved.
+ *
+ * This software is distributed under the terms of the GNU General Public
+ * License v3 (GPL Version 3), copied verbatim in the file "COPYING".
+ *
+ * In applying this license CERN does not waive the privileges and immunities
+ * granted to it by virtue of its status as an Intergovernmental Organization
+ * or submit itself to any jurisdiction.
+*/
+
+import sessionService from '/js/src/sessionService.js';
+sessionService.loadAndHideParameters();
diff --git a/Framework/docs/tutorial/time-server.md b/Framework/docs/tutorial/time-server.md
index 64e0b83ac..40100dc34 100644
--- a/Framework/docs/tutorial/time-server.md
+++ b/Framework/docs/tutorial/time-server.md
@@ -1,5 +1,5 @@
# Tutorial - Time server
-This tutorial coverts development of a simple time server. The server provides time from two sources:
+This tutorial covers development of a simple time server. The server provides time from two sources:
* HTTP server on a request
* WebSocket server via server push
@@ -32,12 +32,19 @@ Start the server: `node index.js`.
Then, open your browser and navigate to [http://localhost:8080](http://localhost:8080). You should see the final result. Click on `++` and `--` to change the local counter, or use two other buttons to request the date.
### Files overview
-* `package.json` - NodeJS file with dependencies and scripts
-* `config.js` - Application configuration file (HTTP endpoint configuration)
-* `index.js` - Server's root file
-* `public/Model.js` - Front-end model
-* `public/view.js` - Front-end view
-* `public/index.html` - Main front-end web page, also contains simple controller
+```
+newproject/
+├─ config.js # application configuration file (HTTP endpoint configuration)
+├─ index.js # server's root file
+├─ public/
+│ ├─ index.html # main front-end web page; minimal HTML; links CSS; loads external modules (CSP-safe)
+│ ├─ session.js # reads URL params via sessionService and hides them
+│ ├─ app.js # controller: imports Model + view, mounts the app
+│ ├─ Model.js # observable model (counter, HTTP date fetch, WS streaming)
+│ └─ view.js # hyperscript view rendering the UI
+├─ package.json # NodeJS file with dependencies and scripts
+└─ time-server.md # this tutorial document
+```
### Server side explained
@@ -54,7 +61,7 @@ const config = require('./config.js');
```
#### HTTP
-Afterwards an instance of the HTTP server is created and `./public` folder served (`http://localhost:8080/`).
+Afterwards an instance of the HTTP server is created and the `./public` folder is served (`http://localhost:8080/`).
```js
const httpServer = new HttpServer(config.httpM);
httpServer.addStaticPath('./public');
@@ -68,7 +75,7 @@ httpServer.post('/getDate', (req, res) => {
```
#### WebSockets
It's also possible to speak with the server using WebSocket protocol. It happens either in request-reply mode or as server broadcast (to all connected clients).
-The code below accepts `stream-date` as a signal to start sending time information. It will push the current time every 100ms with message command set to `server-date`. If the `stream-date` command is received once again it will stop the updates.
+The code below accepts `stream-date` as a signal to start sending time information. It will push the current time every 100ms with message command set to `server-date`. If the `stream-date` command is received once again it will stop the updates.
```js
const wsServer = new WebSocket(httpServer);
@@ -94,22 +101,24 @@ wsServer.bind('stream-date', (body) => {
### Client side explained - Controller
-Open `public/index.html` file. In the 3rd line CSS bootstrap is imported.
+`public/index.html` contains the framework stylesheet and two ES modules (`session.js` and `app.js`).
```html
+
+
```
-It includes session service that recovers variables provided by the server via URL and store them in a global context.
+The `public/session.js` module includes session service that recovers variables provided by the server via URL and stores them in a global context.
```js
import sessionService from '/js/src/sessionService.js';
sessionService.loadAndHideParameters();
```
-Then the MVC files are imported using Javascript modules.
+Then, in the `public/app.js` module, the MVC files are imported.
```js
import {mount} from '/js/src/index.js';
import view from './view.js';
-import Model from './model.js';
+import Model from './Model.js';
```
And finally, the instance of model is created and `mount` called.
@@ -120,9 +129,18 @@ const debug = true; // shows when redraw is done
mount(document.body, view, model, debug);
```
+This avoids inline `