Revert "Session version" (#1649)

* Revert "refactor: add version to session endpoint"

This reverts commit cd40a6e55e.

* Revert "Remove public event feature (#1645)"

This reverts commit 08d9e24871.

* Revert "Fix: rearrange playing event (#1640)"

This reverts commit 0649678dca.

* Revert "refactor: style tweaks to edit css modal"

This reverts commit a00ec2d02a.

* Revert "refactor: remove usages of framer-motion"

This reverts commit 54a74ccc2a.

* Revert "Upgrade expressjs (#1633)"

This reverts commit 6f3ab274bd.

* Revert "Refactor: require trigger in all events objects (#1636)"

This reverts commit 90870ecfb6.

* Revert "Fix: Correct boundary condition in applyDelay"

This reverts commit b640e0e181.

* Revert "let vite be the proxy to the dev server (#1630)"

This reverts commit c41fe824cf.

* Revert "refactor: migrate custom fields to transactions"

This reverts commit 62c8319d70.

* Revert "refactor: simplify validations"

This reverts commit b1d23467a2.

* Revert "refactor: create transaction system and apply to adding entry (#1620)"

This reverts commit 9a62daf047.

* Revert "Refactor: better rounding (#1594)"

This reverts commit b9ab1c6fd7.

* Revert "refactor: improve reorder logic"

This reverts commit c1054711b0.

* Revert "chore: simplify URLs"

This reverts commit a4d4f29a37.

* Revert "refactor: order is single source of truth"

This reverts commit 2793aadea0.

* Revert "refactor: refetch targets is enum"

This reverts commit e7cfb7d9d9.

* Revert "refactor: small ux improvements"

This reverts commit 256a851c9b.

* Revert "refactor: remove trivially inferred numEvents"

This reverts commit 4ab9c81cb8.

* Revert "feat: duplicate groups"

This reverts commit 2f13d6c89e.

* Revert "feat: create group from entry selection"

This reverts commit f1f7bad25e.

* Revert "feat: create block from rundown empty"

This reverts commit a8b52a48f7.

* Revert "fix: collapsed blocks dont render children"

This reverts commit cd0999b2ab.

* Revert "refactor: type cleanup and test improvements"

This reverts commit b4c60f3f04.

* Revert "feat: allow dissolving a block"

This reverts commit 5cefad3666.

* Revert "fix: uncontrolled prop on controlled component"

This reverts commit 7a6ecd8c34.

* Revert "refactor: improve return of reorder"

This reverts commit ba96ecfd91.

* Revert "refactor: mutations on batch elements must have IDs"

This reverts commit 7bed3757f2.

* Revert "chore: upgrade dependencies"

This reverts commit e2e755b1d2.

* Revert "refactor: extract utility to merge two arrays"

This reverts commit a77d23109d.

* Revert "refactor: change network mode defaults"

This reverts commit 0eb3b8d382.

* Revert "fix: delete nested events"

This reverts commit 0021185288.

* Revert "fix: add event at end of block"

This reverts commit 94c72ff4f6.

* Revert "refactor: make finder available in exported rundown"

This reverts commit e4c08dc9b2.

* Revert "assert non null and update test (#1604)"

This reverts commit ec74af0d62.

* Revert "Fix project renumber (#1597)"

This reverts commit b6d72dd082.

* Revert "Refactor: WebSocket from flush queue to one patch (#1595)"

This reverts commit 31c311daf0.

* Revert "Refactor: ms for api calls (#1593)"

This reverts commit e9b3cc6090.

* Revert "fix test (#1601)"

This reverts commit 543b04a097.

* Revert "fix: rebase master"

This reverts commit d39b85b6e6.

* Revert "chore: correct test path"

This reverts commit bbe107bb2b.

* Revert "refactor: extract rundown parsing"

This reverts commit c616240db1.

* Revert "chore: improve convention entry <> event"

This reverts commit 166be66ce3.

* Revert "refactor: maintain flat orders"

This reverts commit 4180d0a337.

* Revert "refactor: implement operations on nested events"

This reverts commit 78108e316c.

* Revert "refactor: process events in rundown"

This reverts commit 3bb8b70915.

* Revert "chore: improve convention entry <> event"

This reverts commit 1c4f13a0ed.

* Revert "chore: rename currentBlock > parent"

This reverts commit 3ca0abad53.

* Revert "refactor: fix delay positioning in gaps"

This reverts commit 030c8f897f.

* Revert "refactor(e2e): skip flaky test"

This reverts commit 68175cfa3b.

* Revert "refactor: improve project loading"

This reverts commit fd8f757851.

* Revert "refactor: gather group metadata"

This reverts commit 876d111c61.

* Revert "refactor: swap maintains schedule"

This reverts commit 730cb95c04.

* Revert "chore: rename files"

This reverts commit 3c388d4fb5.

* Revert "refactor: restructure model to contain an object of rundowns"

This reverts commit 2e23718d73.

* Revert "refactor: clearer relationship on rundown elements"

This reverts commit 89ea8c470b.

* Revert "refactor: use strict typing"

This reverts commit 178640bfc4.

* Revert "refactor: remove stop as a possible end action"

This reverts commit 4ed38340e0.

* Revert "refactor: restructure model to contain an object of rundowns"

This reverts commit 69eb9a5eff.

* Revert "chore: remove IDE files"

This reverts commit 351425127a.

* Revert "refactor: remove unused and legacy code"

This reverts commit 95f2ba37cc.
This commit is contained in:
Alex Christoffer Rasmussen
2025-06-20 12:28:20 +02:00
committed by GitHub
parent ad6804019b
commit 722e045b20
366 changed files with 13067 additions and 13052 deletions
+2 -2
View File
@@ -1,9 +1,9 @@
import { Log, LogLevel } from 'ontime-types';
import { generateId, millisToString } from 'ontime-utils';
import { clock } from '../services/Clock.js';
import { socket } from '../adapters/WebsocketAdapter.js';
import { consoleSubdued, consoleError } from '../utils/console.js';
import { timeNow } from '../utils/time.js';
import { isProduction } from '../setup/environment.js';
class Logger {
@@ -75,7 +75,7 @@ class Logger {
level,
origin,
text,
time: millisToString(timeNow()),
time: millisToString(clock.getSystemTime() || 0),
};
this._push(log);
}
@@ -1,13 +1,12 @@
import {
ProjectData,
OntimeRundown,
ViewSettings,
DatabaseModel,
Settings,
CustomFields,
URLPreset,
AutomationSettings,
Rundown,
ProjectRundowns,
} from 'ontime-types';
import type { Low } from 'lowdb';
@@ -23,9 +22,6 @@ type ReadonlyPromise<T> = Promise<Readonly<T>>;
let db = {} as Low<DatabaseModel>;
/**
* Initialises the JSON adapter to persist data to a file
*/
export async function initPersistence(filePath: string, fallbackData: DatabaseModel) {
// eslint-disable-next-line no-unused-labels -- dev code path
DEV: shouldCrashDev(!isPath(filePath), 'initPersistence should be called with a path');
@@ -49,7 +45,6 @@ export function getDataProvider() {
setCustomFields,
getCustomFields,
setRundown,
mergeRundown,
getSettings,
setSettings,
getUrlPresets,
@@ -83,28 +78,14 @@ async function setCustomFields(newData: CustomFields): ReadonlyPromise<CustomFie
return db.data.customFields;
}
async function mergeRundown(
newCustomFields: CustomFields,
newRundowns: ProjectRundowns,
): ReadonlyPromise<{ rundowns: ProjectRundowns; customFields: CustomFields }> {
db.data.customFields = { ...db.data.customFields, ...newCustomFields };
Object.entries(newRundowns).forEach(([id, rundown]) => {
// Note that entries with the same key will be overridden
db.data.rundowns[id] = rundown;
});
await persist();
return { rundowns: db.data.rundowns, customFields: db.data.customFields };
}
function getCustomFields(): Readonly<CustomFields> {
return db.data.customFields;
}
async function setRundown(rundownKey: string, newData: Rundown): ReadonlyPromise<Rundown> {
db.data.rundowns[rundownKey] = newData;
async function setRundown(newData: OntimeRundown): ReadonlyPromise<OntimeRundown> {
db.data.rundown = newData;
await persist();
return db.data.rundowns[rundownKey];
return db.data.rundown;
}
function getSettings(): Readonly<Settings> {
@@ -147,9 +128,8 @@ async function setAutomation(newData: AutomationSettings): ReadonlyPromise<Autom
return db.data.automation;
}
function getRundown(): Readonly<Rundown> {
const firstRundown = Object.keys(db.data.rundowns)[0];
return db.data.rundowns[firstRundown];
function getRundown(): Readonly<OntimeRundown> {
return db.data.rundown;
}
async function mergeIntoData(newData: Partial<DatabaseModel>): ReadonlyPromise<DatabaseModel> {
@@ -160,7 +140,7 @@ async function mergeIntoData(newData: Partial<DatabaseModel>): ReadonlyPromise<D
db.data.automation = mergedData.automation;
db.data.urlPresets = mergedData.urlPresets;
db.data.customFields = mergedData.customFields;
db.data.rundowns = mergedData.rundowns;
db.data.rundown = mergedData.rundown;
await persist();
return db.data;
@@ -8,7 +8,7 @@ export function safeMerge(existing: DatabaseModel, newData: Partial<DatabaseMode
const deepNewData = structuredClone(newData);
const {
rundowns = {},
rundown = deepExisting.rundown,
project = {},
settings = {},
viewSettings = {},
@@ -19,7 +19,7 @@ export function safeMerge(existing: DatabaseModel, newData: Partial<DatabaseMode
return {
...deepExisting,
rundowns: { ...existing.rundowns, ...rundowns },
rundown,
project: { ...deepExisting.project, ...project },
settings: { ...deepExisting.settings, ...settings },
viewSettings: { ...deepExisting.viewSettings, ...viewSettings },
@@ -1,48 +1,73 @@
import { DatabaseModel, Settings, URLPreset } from 'ontime-types';
import { demoDb } from '../../../models/demoProject.js';
import { makeOntimeEvent, makeRundown } from '../../../api-data/rundown/__mocks__/rundown.mocks.js';
import { DatabaseModel, OntimeRundown, Settings, URLPreset, ViewSettings } from 'ontime-types';
import { safeMerge } from '../DataProvider.utils.js';
describe('safeMerge', () => {
const existing = {
rundown: [],
project: {
title: 'existing title',
description: 'existing description',
publicUrl: 'existing public URL',
backstageUrl: 'existing backstageUrl',
publicInfo: 'existing backstageInfo',
backstageInfo: 'existing backstageInfo',
projectLogo: null,
custom: [
{
title: 'existing custom title',
value: 'existing custom value',
},
],
},
settings: {
app: 'ontime',
version: '2.0.0',
serverPort: 4001,
editorKey: null,
operatorKey: null,
timeFormat: '24',
language: 'en',
},
viewSettings: {
overrideStyles: false,
freezeEnd: false,
endMessage: 'existing endMessage',
normalColor: '#ffffffcc',
warningColor: '#FFAB33',
dangerColor: '#ED3333',
},
urlPresets: [],
customFields: {
lighting: { type: 'string', label: 'lighting', colour: 'red' },
vfx: { type: 'string', label: 'vfx', colour: 'blue' },
},
automation: {
enabledAutomations: false,
enabledOscIn: false,
oscPortIn: 8000,
triggers: [],
automations: {},
},
} as DatabaseModel;
it('returns existing data if new data is not provided', () => {
const mergedData = safeMerge(demoDb, {});
expect(mergedData).toEqual(demoDb);
const mergedData = safeMerge(existing, {});
expect(mergedData).toEqual(existing);
});
it('overrides a rundown with the same key', () => {
const newData = makeRundown({
id: 'demo',
entries: {
'1': makeOntimeEvent({ id: '1', title: 'new title' }),
'2': makeOntimeEvent({ id: '1', title: 'new title' }),
},
order: ['1', '2'],
});
const mergedData = safeMerge(demoDb, { rundowns: { demo: newData } });
expect(mergedData.rundowns.demo).toStrictEqual(newData);
});
it('merges a rundown with a new key', () => {
const newData = makeRundown({
id: 'rundown',
entries: {
'1': makeOntimeEvent({ id: '1', title: 'new title' }),
'2': makeOntimeEvent({ id: '1', title: 'new title' }),
},
order: ['1', '2'],
});
const mergedData = safeMerge(demoDb, { rundowns: { rundown: newData } });
expect(mergedData.rundowns.demo).toStrictEqual(demoDb.rundowns.demo);
expect(mergedData.rundowns.rundown).toStrictEqual(newData);
it('merges the rundown key', () => {
const newData = {
rundown: [{ title: 'item 1' }, { title: 'item 2' }] as OntimeRundown,
};
const mergedData = safeMerge(existing, newData);
expect(mergedData.rundown).toEqual(newData.rundown);
});
it('merges the project key', () => {
const mergedData = safeMerge(demoDb, {
const newData = {
project: {
title: 'new title',
backstageInfo: 'new backstage info',
publicInfo: 'new public info',
custom: [
{
title: 'new custom title',
@@ -50,13 +75,16 @@ describe('safeMerge', () => {
},
],
},
} as Partial<DatabaseModel>);
expect(mergedData.project).toStrictEqual({
};
// @ts-expect-error -- just testing
const mergedData = safeMerge(existing, newData);
expect(mergedData.project).toEqual({
title: 'new title',
description: 'Turin 2022',
backstageUrl: 'www.github.com/cpvalente/ontime',
backstageInfo: 'new backstage info',
description: 'existing description',
publicUrl: 'existing public URL',
publicInfo: 'new public info',
backstageUrl: 'existing backstageUrl',
backstageInfo: 'existing backstageInfo',
projectLogo: null,
custom: [
{
@@ -68,15 +96,16 @@ describe('safeMerge', () => {
});
it('merges the settings key', () => {
const mergedData = safeMerge(demoDb, {
const newData = {
settings: {
serverPort: 3000,
language: 'pt',
version: 'new',
} as Settings,
});
expect(mergedData.settings).toStrictEqual({
version: 'new',
};
const mergedData = safeMerge(existing, newData);
expect(mergedData.settings).toEqual({
app: 'ontime',
version: '2.0.0',
serverPort: 3000,
operatorKey: null,
editorKey: null,
@@ -86,6 +115,42 @@ describe('safeMerge', () => {
});
it('should merge the urlPresets key when present', () => {
const existingData = {
rundown: [],
project: {
title: '',
description: '',
publicUrl: '',
publicInfo: '',
backstageUrl: '',
backstageInfo: '',
projectLogo: null,
custom: [],
},
settings: {
app: 'ontime',
version: '2.0.0',
serverPort: 4001,
operatorKey: null,
editorKey: null,
timeFormat: '24',
language: 'en',
},
viewSettings: {
overrideStyles: false,
endMessage: '',
} as ViewSettings,
urlPresets: [],
customFields: {},
automation: {
enabledAutomations: false,
enabledOscIn: false,
oscPortIn: 8000,
triggers: [],
automations: {},
},
} as DatabaseModel;
const newData = {
urlPresets: [
{ enabled: true, alias: 'alias1', pathAndParams: '' },
@@ -93,9 +158,9 @@ describe('safeMerge', () => {
] as URLPreset[],
};
const mergedData = safeMerge(demoDb, newData);
const mergedData = safeMerge(existingData, newData);
expect(mergedData.urlPresets).toStrictEqual(newData.urlPresets);
expect(mergedData.urlPresets).toEqual(newData.urlPresets);
});
it('merges customFields into existing object', () => {
@@ -86,12 +86,6 @@ export class SimpleTimer {
public update(timeNow: number): SimpleTimerState {
if (this.state.playback === SimplePlayback.Start) {
// we know startedAt is not null since we are in play mode
// eslint-disable-next-line no-unused-labels -- dev code path
DEV: {
if (this.startedAt === null) {
throw new Error('SimpleTimer.update: invalid state received');
}
}
const elapsed = timeNow - this.startedAt;
if (this.state.direction === SimpleDirection.CountDown) {
this.state.current = this.state.duration - elapsed;