Merge final group into main #3

Merged
quic merged 10 commits from group-26d3b827-6587-46c2-a46e-001281299174 into main 2026-05-10 20:10:02 +00:00
3 changed files with 38 additions and 3 deletions
Showing only changes of commit 043e813864 - Show all commits

View File

@@ -1,5 +1,6 @@
import * as Y from "yjs"; import * as Y from "yjs";
import { getDeadline } from "../state"; import { getDeadline } from "../state";
import { enforceAppendOnly } from "../yDocUtil";
const DEADLINE_DURATION_MS = 2 * 60 * 1000; // 2 minutes const DEADLINE_DURATION_MS = 2 * 60 * 1000; // 2 minutes
@@ -79,7 +80,7 @@ export function DeadlineTimer(
onClearDeadline(); onClearDeadline();
}); });
deadlineMap.observe(() => render()); deadlineMap.observe(enforceAppendOnly(deadlineMap,render));
render(); render();
return wrapper; return wrapper;

View File

@@ -1,6 +1,7 @@
import * as Y from "yjs"; import * as Y from "yjs";
import type { OptionRecord } from "../state"; import type { OptionRecord } from "../state";
import { PollOption } from "./PollOption"; import { PollOption } from "./PollOption";
import { enforceAppendOnly } from "../yDocUtil";
export function PollList( export function PollList(
yOptions: Y.Map<OptionRecord>, yOptions: Y.Map<OptionRecord>,
@@ -119,8 +120,8 @@ export function PollList(
}); });
} }
yOptions.observeDeep(() => render()); yOptions.observe(enforceAppendOnly(yOptions,render));
yVotes.observe(() => render()); yVotes.observe(enforceAppendOnly(yVotes,render));
render(); render();
return wrapper; return wrapper;

33
src/yDocUtil.ts Normal file
View File

@@ -0,0 +1,33 @@
import * as Y from "yjs";
/**
* Enforces append-only logic on a Y.Map.
* Reverts any 'update' or 'delete' actions detected in the observer.
*/
export function enforceAppendOnly(yMap: Y.Map<any>,render: () => void) {
return (event: Y.YMapEvent<any>, transaction: Y.Transaction) => {
// Avoid infinite loops: check if this change was
// triggered by our own 'undo' logic.
if (transaction.origin === 'revert-logic') return;
event.keys.forEach((change, key) => {
const { action, oldValue } = change;
if (action === 'update' || action === 'delete') {
// Use the transaction to undo the illegal operation
yMap.doc?.transact(() => {
if (action === 'update' && oldValue !== undefined) {
// Revert to previous value
yMap.set(key, oldValue);
} else if (action === 'delete' && oldValue !== undefined) {
// Restore the deleted key
yMap.set(key, oldValue);
}
console.warn(`Illegal ${action} attempt on key: "${key}". Reverted.`);
}, 'revert-logic');
}
});
render();
};
}