Merge final group into main #3
@@ -1,5 +1,6 @@
|
||||
import * as Y from "yjs";
|
||||
import { getDeadline } from "../state";
|
||||
import { enforceAppendOnly } from "../yDocUtil";
|
||||
|
||||
const DEADLINE_DURATION_MS = 2 * 60 * 1000; // 2 minutes
|
||||
|
||||
@@ -79,7 +80,7 @@ export function DeadlineTimer(
|
||||
onClearDeadline();
|
||||
});
|
||||
|
||||
deadlineMap.observe(() => render());
|
||||
deadlineMap.observe(enforceAppendOnly(deadlineMap,render));
|
||||
render();
|
||||
|
||||
return wrapper;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as Y from "yjs";
|
||||
import type { OptionRecord } from "../state";
|
||||
import { PollOption } from "./PollOption";
|
||||
import { enforceAppendOnly } from "../yDocUtil";
|
||||
|
||||
export function PollList(
|
||||
yOptions: Y.Map<OptionRecord>,
|
||||
@@ -119,8 +120,8 @@ export function PollList(
|
||||
});
|
||||
}
|
||||
|
||||
yOptions.observeDeep(() => render());
|
||||
yVotes.observe(() => render());
|
||||
yOptions.observe(enforceAppendOnly(yOptions,render));
|
||||
yVotes.observe(enforceAppendOnly(yVotes,render));
|
||||
render();
|
||||
|
||||
return wrapper;
|
||||
|
||||
33
src/yDocUtil.ts
Normal file
33
src/yDocUtil.ts
Normal 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();
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user