Skip to content

Instantly share code, notes, and snippets.

@rads
Last active December 6, 2019 22:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rads/7b11c3f8cc67bc36698dff93a002cd14 to your computer and use it in GitHub Desktop.
Save rads/7b11c3f8cc67bc36698dff93a002cd14 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
// =============================================================================
// Updating the Visualization
//
// The code after this comment can be copy-pasted into the XState Visualizer:
// https://xstate.js.org/viz/
// =============================================================================
const incErrorCount = assign({ errorCount: (ctx, event) => ctx.errorCount + 1 });
const incInitCount = assign({ initCount: (ctx, event) => ctx.initCount + 1 });
const incRecoveryCount = assign({ recoveryCount: (ctx, event) => ctx.recoveryCount + 1 });
const setCurrentEditor = assign({ currentEditor: (context, event) => event.editor });
const setPendingInitializationTrue = assign({ pendingInitialization: (context, event) => true });
const setPendingInitializationFalse = assign({ pendingInitialization: (context, event) => false });
const setLastError = assign({ lastError: (context, event) => event.error });
function isNotPendingInitialization(context, event) {
return !context.pendingInitialization;
}
function isMaxErrors(context, event) {
return context.errorCount > 2;
}
function isVersionMismatch(context, event) {
const { currentEditor } = context;
const clientEngineVersion = currentEditor && currentEditor.plugins
.get('RealTimeCollaborationClient').service._engineVersion;
return (
window._CK_ENGINE_VERSION &&
clientEngineVersion !== window._CK_ENGINE_VERSION
);
}
function randInt(start, end) {
return start + Math.floor(Math.random() * Math.floor(end - start));
}
const recoveryTimeoutDelay = 1000;
function recoveryStartDelay(context, event) {
return (context.recoveryCount === 1) ? 0 : randInt(1000, 3000);
}
function createMachine(options) {
return Machine({
id: 'supervisor',
initial: 'started',
context: {
initEditor: options.initEditor,
windowEvents: options.windowEvents,
sendRecoveryRequest: options.sendRecoveryRequest,
docEvents: options.docEvents,
requestRefresh: options.requestRefresh,
beforeDestroy: options.beforeDestroy,
online: navigator.onLine,
currentEditor: null,
errorCount: 0,
initCount: 0,
recoveryCount: 0,
pendingInitialization: false,
lastError: null
},
states: {
stopping: {
on: {
'': { cond: isNotPendingInitialization, target: 'stopped' },
initSuccess: 'stopped',
initError: 'stopped'
}
},
stopped: {
entry: 'destroyEditor',
type: 'final'
},
started: {
initial: 'online',
on: {
stop: 'stopping',
maxErrors: '.manualRefresh',
versionMismatch: '.manualRefresh',
recoveryTimeout: '.manualRefresh'
},
states: {
manualRefresh: {
type: 'final',
entry: 'requestRefresh'
},
offline: {
on: {
online: 'online'
}
},
online: {
invoke: {
id: 'addEventListeners',
src: 'addEventListeners'
},
initial: 'initializing',
on: {
offline: 'offline',
flushReceived: '.initializing',
errorDetected: '.error'
},
states: {
initializing: {
entry: [incInitCount, setPendingInitializationTrue, 'destroyEditor'],
exit: [setPendingInitializationFalse],
invoke: {
id: 'initializeEditor',
src: 'initializeEditor'
},
on: {
initSuccess: { target: 'editing', actions: setCurrentEditor },
initError: { target: 'error', actions: 'sendErrorDetected' }
}
},
editing: { },
error: {
entry: [
incErrorCount,
setLastError
],
on: {
'': [
{
cond: isMaxErrors,
actions: send('maxErrors'),
target: 'failed'
},
{
cond: 'isRecoveryTimeout',
actions: send('recoveryTimeout'),
target: 'failed'
},
{ target: 'recovering' }
]
}
},
failed: { type: 'final' },
recovering: {
initial: 'starting',
states: {
starting: {
entry: incRecoveryCount,
after: { recoveryStartDelay: 'sendingRequest' }
},
sendingRequest: {
entry: [
'sendRecoveryRequest',
'startRecoveryTimeout',
],
on: {
'': [
{
cond: isVersionMismatch,
actions: send('versionMismatch'),
target: 'waiting'
},
{ target: 'waiting' }
]
}
},
waiting: {
exit: 'cancelRecoveryTimeout'
}
}
}
}
}
}
}
}
}, {
activities: options.activities,
actions: options.actions,
guards: options.guards,
services: options.services,
delays: {
recoveryStartDelay,
recoveryTimeoutDelay
}
});
}
// Uncomment the following line for the visualizer:
const machine = createMachine({});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment