mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-16 04:43:35 +00:00
V2 beta3 (#338)
* chore: upgrade local build documentation * style: keep scrolling event in screen * feat: delay is time entry * refactor: remove unused * refactor: remove unused * refactor: batch store updates * refactor: virtually remove cap on events * refactor: style and behaviour tweaks to event block * style: tweaks on schedules * chore: remove sentry from server * style: reorder menu * chore: update docs
This commit is contained in:
@@ -6,7 +6,6 @@ import cors from 'cors';
|
||||
// import utils
|
||||
import { join, resolve } from 'path';
|
||||
|
||||
import { initSentry, reportSentryException } from './modules/sentry.js';
|
||||
import { currentDirectory, environment, externalsStartDirectory, isProduction, resolvedPath } from './setup.js';
|
||||
import { ONTIME_VERSION } from './ONTIME_VERSION.js';
|
||||
import { OSCSettings } from 'ontime-types';
|
||||
@@ -39,8 +38,6 @@ if (!isProduction) {
|
||||
console.log(`Ontime directory at ${currentDirectory} `);
|
||||
}
|
||||
|
||||
initSentry(isProduction);
|
||||
|
||||
// Create express APP
|
||||
const app = express();
|
||||
app.disable('x-powered-by');
|
||||
@@ -209,14 +206,12 @@ export const shutdown = async (exitCode = 0) => {
|
||||
|
||||
process.on('exit', (code) => console.log(`Ontime exited with code: ${code}`));
|
||||
|
||||
process.on('unhandledRejection', async (error) => {
|
||||
reportSentryException(error);
|
||||
process.on('unhandledRejection', async () => {
|
||||
logger.error('SERVER', 'Error: unhandled rejection');
|
||||
await shutdown(1);
|
||||
});
|
||||
|
||||
process.on('uncaughtException', async (error) => {
|
||||
reportSentryException(error);
|
||||
process.on('uncaughtException', async () => {
|
||||
logger.error('SERVER', 'Error: uncaught exception');
|
||||
await shutdown(1);
|
||||
});
|
||||
|
||||
@@ -260,9 +260,11 @@ export class EventLoader {
|
||||
* Handle side effects from event loading
|
||||
*/
|
||||
private _loadEvent() {
|
||||
eventStore.set('loaded', this.loaded);
|
||||
eventStore.set('titles', this.titles);
|
||||
eventStore.set('titlesPublic', this.titlesPublic);
|
||||
eventStore.batchSet({
|
||||
loaded: this.loaded,
|
||||
titles: this.titles,
|
||||
titlesPublic: this.titlesPublic,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,7 +7,6 @@ import { ensureDirectory } from '../utils/fileManagement.js';
|
||||
import { validateFile } from '../utils/parserUtils.js';
|
||||
import { dbModel } from '../models/dataModel.js';
|
||||
import { parseJson } from '../utils/parser.js';
|
||||
import { reportSentryException } from './sentry.js';
|
||||
import { pathToStartDb, resolveDbDirectory, resolveDbPath } from '../setup.js';
|
||||
|
||||
/**
|
||||
@@ -22,8 +21,8 @@ const populateDb = () => {
|
||||
if (!existsSync(dbInDisk)) {
|
||||
try {
|
||||
copyFileSync(pathToStartDb, dbInDisk);
|
||||
} catch (error) {
|
||||
reportSentryException(error);
|
||||
} catch (_) {
|
||||
/* we do not handle this */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { copyFileSync, existsSync } from 'fs';
|
||||
import { pathToStartStyles, resolveStylesDirectory, resolveStylesPath } from '../setup.js';
|
||||
import { ensureDirectory } from '../utils/fileManagement.js';
|
||||
import { reportSentryException } from './sentry.js';
|
||||
|
||||
/**
|
||||
* @description ensures directories exist and populates stylesheet
|
||||
@@ -15,8 +14,8 @@ export const populateStyles = () => {
|
||||
if (!existsSync(stylesInDisk)) {
|
||||
try {
|
||||
copyFileSync(pathToStartStyles, stylesInDisk);
|
||||
} catch (error) {
|
||||
reportSentryException(error);
|
||||
} catch (_) {
|
||||
/* we do not handle this */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import * as Sentry from '@sentry/node';
|
||||
|
||||
let shouldReport;
|
||||
|
||||
export function initSentry(doReport) {
|
||||
shouldReport = doReport;
|
||||
Sentry.init({
|
||||
dsn: 'https://ceb6abdce7374857bb50b65636cbaed1@o4504288369836032.ingest.sentry.io/4504288555565056',
|
||||
tracesSampleRate: 1.0,
|
||||
});
|
||||
}
|
||||
|
||||
export function reportSentryException(e) {
|
||||
if (shouldReport) {
|
||||
Sentry.captureException(e);
|
||||
} else {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,17 @@
|
||||
import { OntimeBaseEvent, OntimeBlock, OntimeDelay, OntimeEvent, SupportedEvent } from 'ontime-types';
|
||||
import {
|
||||
OntimeBaseEvent,
|
||||
OntimeBlock,
|
||||
OntimeDelay,
|
||||
OntimeEvent,
|
||||
SupportedEvent,
|
||||
} from 'ontime-types';
|
||||
import { generateId } from 'ontime-utils';
|
||||
import { DataProvider } from '../classes/data-provider/DataProvider.js';
|
||||
import { block as blockDef, delay as delayDef, event as eventDef } from '../models/eventsDefinition.js';
|
||||
import {
|
||||
block as blockDef,
|
||||
delay as delayDef,
|
||||
event as eventDef,
|
||||
} from '../models/eventsDefinition.js';
|
||||
import { MAX_EVENTS } from '../settings.js';
|
||||
import { EventLoader, eventLoader } from '../classes/event-loader/EventLoader.js';
|
||||
import { eventTimer } from './TimerService.js';
|
||||
@@ -216,30 +226,27 @@ export async function reorderEvent(eventId, from, to) {
|
||||
* @param eventId
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function applyDelay(eventId) {
|
||||
export async function applyDelay(eventId: string) {
|
||||
const rundown = DataProvider.getRundown();
|
||||
let delayIndex = null;
|
||||
let delayValue = 0;
|
||||
|
||||
for (const [index, e] of rundown.entries()) {
|
||||
for (const [index, event] of rundown.entries()) {
|
||||
// look for delay
|
||||
if (delayIndex === null) {
|
||||
if (e.id === eventId && e.type === SupportedEvent.Delay) {
|
||||
delayValue = e.duration;
|
||||
if (event.id === eventId && event.type === SupportedEvent.Delay) {
|
||||
delayValue = event.duration;
|
||||
delayIndex = index;
|
||||
}
|
||||
}
|
||||
|
||||
// apply delay value to all items until block or end
|
||||
else {
|
||||
if (e.type === SupportedEvent.Event) {
|
||||
// update times
|
||||
e.timeStart += delayValue;
|
||||
e.timeEnd += delayValue;
|
||||
|
||||
// increment revision
|
||||
e.revision += 1;
|
||||
} else if (e.type === SupportedEvent.Block) {
|
||||
if (event.type === SupportedEvent.Event) {
|
||||
event.timeStart = Math.max(0, event.timeStart + delayValue);
|
||||
event.timeEnd = Math.max(event.duration, event.timeStart + delayValue);
|
||||
event.revision += 1;
|
||||
} else if (event.type === SupportedEvent.Block) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,8 +141,10 @@ export class TimerService {
|
||||
* @private
|
||||
*/
|
||||
_onLoad() {
|
||||
eventStore.set('playback', this.playback);
|
||||
eventStore.set('timer', this.timer);
|
||||
eventStore.batchSet({
|
||||
playback: this.playback,
|
||||
timer: this.timer,
|
||||
});
|
||||
integrationService.dispatch(TimerLifeCycle.onLoad);
|
||||
}
|
||||
|
||||
@@ -182,8 +184,10 @@ export class TimerService {
|
||||
* @private
|
||||
*/
|
||||
_onStart() {
|
||||
eventStore.set('playback', this.playback);
|
||||
eventStore.set('timer', this.timer);
|
||||
eventStore.batchSet({
|
||||
playback: this.playback,
|
||||
timer: this.timer,
|
||||
});
|
||||
integrationService.dispatch(TimerLifeCycle.onStart);
|
||||
}
|
||||
|
||||
@@ -199,8 +203,10 @@ export class TimerService {
|
||||
}
|
||||
|
||||
_onPause() {
|
||||
eventStore.set('playback', this.playback);
|
||||
eventStore.set('timer', this.timer);
|
||||
eventStore.batchSet({
|
||||
playback: this.playback,
|
||||
timer: this.timer,
|
||||
});
|
||||
integrationService.dispatch(TimerLifeCycle.onPause);
|
||||
}
|
||||
|
||||
@@ -214,8 +220,10 @@ export class TimerService {
|
||||
}
|
||||
|
||||
_onStop() {
|
||||
eventStore.set('playback', this.playback);
|
||||
eventStore.set('timer', this.timer);
|
||||
eventStore.batchSet({
|
||||
playback: this.playback,
|
||||
timer: this.timer,
|
||||
});
|
||||
integrationService.dispatch(TimerLifeCycle.onStop);
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export const MAX_EVENTS = 255;
|
||||
@@ -0,0 +1 @@
|
||||
export const MAX_EVENTS = 32768;
|
||||
@@ -8,6 +8,10 @@ let store: Partial<RuntimeStore> = {};
|
||||
|
||||
/**
|
||||
* A runtime store that broadcasts its payload
|
||||
* - init: allows for adding an initial payload to the store
|
||||
* - batchSet: allows setting several keys with a single broadcast
|
||||
* - poll: utility to return state
|
||||
* - broadcast: send its payload as json object
|
||||
*/
|
||||
export const eventStore = {
|
||||
init(payload: RuntimeStore) {
|
||||
@@ -25,6 +29,12 @@ export const eventStore = {
|
||||
// });
|
||||
this.broadcast();
|
||||
},
|
||||
batchSet<K extends keyof RuntimeStore>(values: Record<K, RuntimeStore[K]>) {
|
||||
Object.entries(values).forEach(([key, value]) => {
|
||||
store[key] = value;
|
||||
});
|
||||
this.broadcast();
|
||||
},
|
||||
poll() {
|
||||
return store;
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user