Last active
December 3, 2020 16:14
-
-
Save karkowg/58e6769261451a5d656e9854c497dacc to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function dayjs() { | |
| return new Date(); | |
| } | |
| function goLive(uid) { | |
| return Promise.resolve({ startedAt: dayjs() }); | |
| } | |
| function stopLive(uid) { | |
| return Promise.resolve(); | |
| } | |
| const makeCountdownMachine = counter => Machine({ | |
| id: 'countdown', | |
| initial: 'running', | |
| context: { | |
| counter, | |
| }, | |
| states: { | |
| running: { | |
| invoke: { | |
| id: 'countdownInterval', | |
| src: () => callback => { | |
| const intervalId = setInterval(() => { | |
| callback('TICK'); | |
| }, 1000); | |
| return () => clearInterval(intervalId); | |
| }, | |
| }, | |
| on: { | |
| '': { | |
| target: 'done', | |
| cond: ctx => ctx.counter <= 0, | |
| }, | |
| TICK: { | |
| actions: ['decrement', 'notify'], | |
| }, | |
| }, | |
| }, | |
| done: { | |
| type: 'final', | |
| }, | |
| }, | |
| }, { | |
| actions: { | |
| decrement: assign({ counter: ctx => ctx.counter - 1 }), | |
| notify: sendParent(ctx => ({ | |
| type: 'COUNTDOWN.UPDATE', | |
| counter: ctx.counter, | |
| })), | |
| }, | |
| }); | |
| const webcastMachine = { | |
| id: 'webcast', | |
| initial: 'default', | |
| states: { | |
| default: { | |
| on: { | |
| '': [ | |
| { target: 'live', cond: 'isLive' }, | |
| { target: 'upcoming' }, | |
| ], | |
| }, | |
| }, | |
| upcoming: { | |
| initial: 'default', | |
| states: { | |
| default: { | |
| on: { | |
| '': [ | |
| { target: 'starting', cond: 'isStarting' }, | |
| { target: 'pre', cond: 'isPre' }, | |
| { target: 'preparing', cond: 'isPreparing' }, | |
| { target: 'idle' }, | |
| ], | |
| }, | |
| }, | |
| idle: { | |
| on: { | |
| PREPARE: 'preparing', | |
| }, | |
| }, | |
| preparing: { | |
| type: 'parallel', | |
| states: { | |
| pexip: { | |
| initial: 'default', | |
| states: { | |
| default: { | |
| on: { | |
| '': [ | |
| { target: 'ready', cond: 'isPexipReady' }, | |
| { target: 'preparing' }, | |
| ], | |
| }, | |
| }, | |
| preparing: { | |
| on: { | |
| PEXIP_VA_READY: { | |
| target: 'ready', | |
| actions: assign({ | |
| isPexipReady: true, | |
| }), | |
| }, | |
| }, | |
| }, | |
| ready: { | |
| type: 'final', | |
| } | |
| }, | |
| }, | |
| mediaLive: { | |
| initial: 'default', | |
| states: { | |
| default: { | |
| on: { | |
| '': [ | |
| { target: 'ready', cond: 'isMediaLiveReady' }, | |
| { target: 'preparing', cond: 'isPreparingMediaLive' }, | |
| { target: 'idle' }, | |
| ], | |
| }, | |
| }, | |
| idle: { | |
| on: { | |
| PREPARE_WEBCAST: 'preparing', | |
| }, | |
| }, | |
| preparing: { | |
| on: { | |
| ML_CHANNEL_READY: { | |
| target: 'ready', | |
| actions: assign({ | |
| isMediaLiveReady: true, | |
| }), | |
| }, | |
| }, | |
| }, | |
| ready: { | |
| type: 'final', | |
| }, | |
| }, | |
| }, | |
| }, | |
| on: { | |
| READY: { | |
| target: 'pre', | |
| cond: ctx => [ctx.isPexipReady, ctx.isMediaLiveReady].every(Boolean), | |
| }, | |
| }, | |
| }, | |
| pre: { | |
| on: { | |
| GO_LIVE: 'starting', | |
| }, | |
| }, | |
| starting: { | |
| invoke: { | |
| id: 'goLive', | |
| src: ctx => goLive(ctx.uid), | |
| }, | |
| on: { | |
| COUNTDOWN: { | |
| actions: 'setLiveContext', | |
| target: '#countdown', | |
| }, | |
| }, | |
| }, | |
| countdown: { | |
| id: 'countdown', | |
| invoke: { | |
| id: 'countdown', | |
| src: (ctx) => makeCountdownMachine(ctx.countdownCounter), | |
| onDone: '#live', | |
| }, | |
| on: { | |
| 'COUNTDOWN.UPDATE': { | |
| actions: 'setCountdownCounter', | |
| }, | |
| }, | |
| }, | |
| }, | |
| }, | |
| live: { | |
| id: 'live', | |
| initial: 'streaming', | |
| on: { | |
| 'ELAPSED.UPDATE': { | |
| actions: 'setElapsed', | |
| }, | |
| 'STATS.UPDATE': { | |
| actions: 'setViewingSessionStats', | |
| }, | |
| STOP_LIVE: 'after', | |
| }, | |
| invoke: [ | |
| // { id: 'elapsed', src: ctx => makeElapsedMachine(ctx.startedAt) }, | |
| // { id: 'stats', src: ctx => makeStatsMachine(ctx.uid) }, | |
| ], | |
| states: { | |
| playback: { | |
| on: { | |
| STOP_VIDEO: 'streaming', | |
| }, | |
| }, | |
| streaming: { | |
| on: { | |
| PLAY_VIDEO: 'playback', | |
| }, | |
| }, | |
| }, | |
| }, | |
| after: { | |
| actions: [ | |
| send('DONE', { to: 'elapsed' }), | |
| send('DONE', { to: 'stats' }), | |
| ], | |
| invoke: { | |
| id: 'stopLive', | |
| src: ctx => stopLive(ctx.uid), | |
| onDone: { | |
| target: '#controlRoom.done', | |
| }, | |
| }, | |
| }, | |
| }, | |
| }; | |
| const makeControlRoomMachine = event => Machine({ | |
| id: 'controlRoom', | |
| initial: 'default', | |
| context: { | |
| countdownCounter: undefined, | |
| elapsed: undefined, | |
| hasFinished: event.event_mode === 'after', | |
| isLive: event.event_mode === 'live', | |
| isMediaLiveReady: event.media_live_state === 'ready', | |
| isPexipReady: event.pexip_state === 'ready', | |
| isPreparing: event.event_mode === 'preparing', | |
| isPreparingMediaLive: event.media_live_state === 'preparing', | |
| isPre: event.event_mode === 'pre', | |
| isStarting: event.event_mode === 'starting', | |
| startedAt: event.start_timecode ?? null, | |
| uid: event.uid, | |
| viewingSessions: { | |
| online: 0, | |
| peak: 0, | |
| total: 0, | |
| }, | |
| }, | |
| states: { | |
| default: { | |
| on: { | |
| '': [ | |
| { target: 'done', cond: 'hasFinished' }, | |
| { target: 'interactive' }, | |
| ], | |
| }, | |
| }, | |
| interactive: { | |
| type: 'parallel', | |
| states: { | |
| webcast: { ...webcastMachine }, | |
| }, | |
| }, | |
| done: { | |
| type: 'final', | |
| }, | |
| }, | |
| }, { | |
| actions: { | |
| setCountdownCounter: assign({ countdownCounter: (ctx, event) => event.counter }), | |
| setElapsed: assign({ elapsed: (ctx, event) => event.elapsed }), | |
| setLiveContext: assign({ | |
| startedAt: (ctx, event) => dayjs(event.starts_at), | |
| countdownCounter: (ctx, event) => event?.countdown ?? 10, | |
| }), | |
| setViewingSessionStats: assign({ viewingSessions: (ctx, event) => event.viewingSessions }), | |
| }, | |
| guards: { | |
| hasFinished: ctx => ctx.hasFinished, | |
| isLive: ctx => ctx.isLive, | |
| isMediaLiveReady: ctx => ctx.isMediaLiveReady, | |
| isPexipReady: ctx => ctx.isPexipReady, | |
| isPreparing: ctx => ctx.isPreparing, | |
| isPreparingMediaLive: ctx => ctx.isPreparingMediaLive, | |
| isPre: ctx => ctx.isPre, | |
| isStarting: ctx => ctx.isStarting, | |
| }, | |
| }); | |
| makeControlRoomMachine({ | |
| uid: 'abc123', | |
| event_mode: 'preparing', | |
| pexip_state: 'ready', | |
| media_live_state: 'idle', | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment