VulpesOS/assets/webapps/system.gaiamobile.org/js/sync_state_machine.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

188 lines
5.4 KiB
JavaScript

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* global BaseModule */
/*
+---------------Success ---------------+
| |
+---+----+ |
|Enabling+---Error---+ |
+---+----+ | |
^ +-v-----+ |
| +-Disable--+Errored+-----------+ |
| | +--+----+ | |
Enable| ^ ^ Enable |
| v | | | |
| +---------+ | | | |
| |Disabling| | | | |
| +-+-------+ | | | |
| | | | v v
+----+---v-+ | +--------+--------+
| Disabled | Error +------->+Enabled +---+
+----------+ | | +---+----+ |
^ ^ | | | |
| | | Success Sync |
| | | | | |
+----+---+--+ | | | |
| Disabling | | | | |
+-----------+ | | | |
^ ^ | | | |
| | | | | |
| Disable | | | |
| | +---+---+ | |
| +--------+|Syncing|<-----------+ |
| +-------+ |
| |
+--------------Disable --------------------+
*/
'use strict';
(function(exports) {
/**
* Object representing the possible transitions and the associated states.
* {
* transitionName: {
* from: to,
* from: to
* ...
* },
* ...
* }
*/
const transitions = {
enable: {
'disabled': 'enabling',
'errored': 'enabled'
},
disable: {
'enabled': 'disabling',
'errored': 'disabling',
'syncing': 'disabling'
},
sync: {'enabled': 'syncing'},
success: {
'disabling': 'disabled',
'enabling' : 'enabled',
'syncing' : 'enabled'
},
error: {
'disabling': 'errored',
'enabled' : 'errored',
'enabling' : 'errored',
'syncing' : 'errored'
}
};
var SyncStateMachine = function() {};
SyncStateMachine.STATES = [
'state' // can be: disabled, enabling, enabled, syncing, disabling or
// errored.
];
SyncStateMachine.SERVICES = [
'enable',
'disable',
'sync',
'success',
'error'
];
SyncStateMachine.SUB_MODULES = [];
BaseModule.create(SyncStateMachine, {
name: 'SyncStateMachine',
DEBUG: false,
EVENT_PREFIX: 'onsync',
_state: 'disabled',
/**
* Creates the state transition function per each event.
*
* This is exposed via Service.request('SyncStateMachine.TRANSITION'),
* where TRANSITION is the name of the transition.
*
* For each successful transition we publish an event in the window object
* with name 'SyncStateMachineSTATE', where STATE is the name of the state
* where the machine transitioned to. This event gets as details an object
* like:
* {
* transition: <string>, // The name of the action that caused the
* // transition.
* from: <string> // The previous state the machine was before this
* // transition.
* }
*
* Example of a transition request 'doB' causing a transition from state
* 'A' to state 'B':
*
* Service.request('SyncStateMachine:doB', 'whatever').then(() => {...});
*
* window.addEventListener('onsyncB', event => {
* event.detail.transition; // 'doB'
* event.detail.from; // 'A'
* event.detail.args; // ["whatever"]
*
* // We can check at this point that the current state is B:
* Service.query('SyncStateMachine.state'); // B
* });
*/
_createTransition: function(name, event) {
return (...args) => {
var from = this._state;
// Checks if the transition is valid in the current state.
if (!transitions[name][this._state]) {
var error = 'Transition ' + name + ' invalid for the current ' +
'state ' + from;
this.debug(error);
throw new Error(error);
}
var to = event[from];
if (from == to) {
return;
}
// Transition to the next state.
this._state = to;
this.debug(`Transition from ${from} to ${to}`, args);
// Publish the syncSTATE event.
this.publish(to, {
transition: name,
from: from,
args: args
});
};
},
_start: function() {
for (var name in transitions) {
if (!transitions.hasOwnProperty(name)) {
continue;
}
this[name] = this._createTransition(name, transitions[name]);
}
},
_stop: function() {}
}, {
state: {
get: function() {
return this._state;
}
}
});
// Exported only for testing purposes.
exports.SyncStateMachineTransitions = transitions;
}(window));