Compare commits

...

1 Commits

Author SHA1 Message Date
Carlos Valente 24e325726c refactor: improve object handling performance 2026-03-14 07:34:02 +01:00
4 changed files with 37 additions and 12 deletions
+1 -3
View File
@@ -139,9 +139,7 @@ export const setEventPlayback = {
pause: () => sendSocket('pause', undefined), pause: () => sendSocket('pause', undefined),
}; };
export const useTimer = createSelector((state: RuntimeStore) => ({ export const useTimer = createSelector((state: RuntimeStore) => state.timer);
...state.timer,
}));
export const useClock = createSelector((state: RuntimeStore) => state.clock); export const useClock = createSelector((state: RuntimeStore) => state.clock);
+6 -1
View File
@@ -223,9 +223,14 @@ class SocketServer implements IAdapter {
// message is any serializable value // message is any serializable value
public sendAsJson<T extends MessageTag>(tag: T, payload: Pick<WsPacketToClient & { tag: T }, 'payload'>['payload']) { public sendAsJson<T extends MessageTag>(tag: T, payload: Pick<WsPacketToClient & { tag: T }, 'payload'>['payload']) {
const wss = this.wss;
if (!wss || wss.clients.size === 0) {
return;
}
try { try {
const stringifiedMessage = JSON.stringify({ tag, payload }); const stringifiedMessage = JSON.stringify({ tag, payload });
this.wss?.clients.forEach((client) => { wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) { if (client.readyState === WebSocket.OPEN) {
client.send(stringifiedMessage); client.send(stringifiedMessage);
} }
@@ -186,7 +186,8 @@ function remove(rundown: Rundown, entry: OntimeEntry) {
// for ontime groups, we need to iterate through the children and delete them // for ontime groups, we need to iterate through the children and delete them
for (let i = 0; i < entry.entries.length; i++) { for (let i = 0; i < entry.entries.length; i++) {
const nestedEntryId = entry.entries[i]; const nestedEntryId = entry.entries[i];
deleteEntry(nestedEntryId); // nested entries are not part of the top-level order
deleteEntry(nestedEntryId, false);
} }
} else if (entry.parent) { } else if (entry.parent) {
// at this point, we are handling entries inside a group, so we need to remove the reference // at this point, we are handling entries inside a group, so we need to remove the reference
@@ -205,10 +206,13 @@ function remove(rundown: Rundown, entry: OntimeEntry) {
edit(rundown, { id: parentGroup.id, entries: filteredEvents }); edit(rundown, { id: parentGroup.id, entries: filteredEvents });
} }
} }
deleteEntry(entry.id); deleteEntry(entry.id);
function deleteEntry(idToDelete: EntryId) { function deleteEntry(idToDelete: EntryId, shouldDeleteFromOrder: boolean = true) {
rundown.order = deleteById(rundown.order, idToDelete); if (shouldDeleteFromOrder) {
rundown.order = deleteById(rundown.order, idToDelete);
}
delete rundown.entries[idToDelete]; delete rundown.entries[idToDelete];
} }
} }
@@ -140,7 +140,6 @@ export async function batchEditEntries(ids: EntryId[], patch: Partial<OntimeEntr
let batchDidInvalidate = false; let batchDidInvalidate = false;
const changedIds: EntryId[] = []; const changedIds: EntryId[] = [];
const patchedEntries: OntimeEntry[] = [];
for (let i = 0; i < ids.length; i++) { for (let i = 0; i < ids.length; i++) {
const currentId = ids[i]; const currentId = ids[i];
const currentEntry = rundown.entries[currentId]; const currentEntry = rundown.entries[currentId];
@@ -165,15 +164,20 @@ export async function batchEditEntries(ids: EntryId[], patch: Partial<OntimeEntr
continue; continue;
} }
const { entry, didInvalidate } = rundownMutation.edit(rundown, { ...patch, id: currentId }); const { didInvalidate } = rundownMutation.edit(rundown, { ...patch, id: currentId });
changedIds.push(currentId); changedIds.push(currentId);
patchedEntries.push(entry);
if (didInvalidate) { if (didInvalidate) {
batchDidInvalidate = true; batchDidInvalidate = true;
} }
} }
// skip commit and notifications when the patch is no-op.
if (changedIds.length === 0) {
return getCurrentRundown() as Rundown;
}
const { rundown: rundownResult, rundownMetadata, revision } = commit(batchDidInvalidate); const { rundown: rundownResult, rundownMetadata, revision } = commit(batchDidInvalidate);
// schedule the side effects // schedule the side effects
@@ -192,7 +196,14 @@ export async function batchEditEntries(ids: EntryId[], patch: Partial<OntimeEntr
* Deletes a known entry from the current rundown * Deletes a known entry from the current rundown
*/ */
export async function deleteEntries(entryIds: EntryId[]): Promise<Rundown> { export async function deleteEntries(entryIds: EntryId[]): Promise<Rundown> {
const currentRundown = getCurrentRundown();
const shouldDelete = entryIds.some((entryId) => Object.hasOwn(currentRundown.entries, entryId));
if (!shouldDelete) {
return currentRundown as Rundown;
}
const { rundown, commit } = createTransaction({ mutableRundown: true, mutableCustomFields: false }); const { rundown, commit } = createTransaction({ mutableRundown: true, mutableCustomFields: false });
const deletedIds: EntryId[] = [];
for (let i = 0; i < entryIds.length; i++) { for (let i = 0; i < entryIds.length; i++) {
const entry = rundown.entries[entryIds[i]]; const entry = rundown.entries[entryIds[i]];
@@ -200,6 +211,11 @@ export async function deleteEntries(entryIds: EntryId[]): Promise<Rundown> {
continue; continue;
} }
rundownMutation.remove(rundown, entry); rundownMutation.remove(rundown, entry);
deletedIds.push(entry.id);
}
if (deletedIds.length === 0) {
return currentRundown as Rundown;
} }
const { rundown: rundownResult, rundownMetadata, revision } = commit(); const { rundown: rundownResult, rundownMetadata, revision } = commit();
@@ -210,7 +226,7 @@ export async function deleteEntries(entryIds: EntryId[]): Promise<Rundown> {
updateRuntimeOnChange(rundownMetadata); updateRuntimeOnChange(rundownMetadata);
// notify timer and external services of change // notify timer and external services of change
notifyChanges(rundownMetadata, revision, { timer: entryIds, external: true }); notifyChanges(rundownMetadata, revision, { timer: deletedIds, external: true });
}); });
return rundownResult; return rundownResult;
@@ -571,8 +587,10 @@ type NotifyChangesOptions = {
* Notify services of changes in the rundown * Notify services of changes in the rundown
*/ */
function notifyChanges(rundownMetadata: RundownMetadata, revision: number, options: NotifyChangesOptions) { function notifyChanges(rundownMetadata: RundownMetadata, revision: number, options: NotifyChangesOptions) {
const shouldNotifyTimer = options.timer === true || (Array.isArray(options.timer) && options.timer.length > 0);
// notify timer service of changed events // notify timer service of changed events
if (options.timer) { if (shouldNotifyTimer) {
runtimeService.notifyOfChangedEvents(rundownMetadata); runtimeService.notifyOfChangedEvents(rundownMetadata);
} }