From 442d0a157d532e6a77bd72b5a82e2c00d45356af Mon Sep 17 00:00:00 2001 From: timmy Date: Mon, 17 Aug 2026 20:43:13 +0000 Subject: [PATCH] fix: preserve Today sync enqueue order --- frontend/today-sync.js | 2 +- src/frontend_bundle.py | 2 +- tests/test_today_sync.py | 25 +++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/frontend/today-sync.js b/frontend/today-sync.js index 4c8dde5..b3532c0 100644 --- a/frontend/today-sync.js +++ b/frontend/today-sync.js @@ -173,7 +173,7 @@ function createTodaySync({ storage, getLogin, fetchJson, onRemoteIds, onRemotePl const recordKey = storageKey + '.operation.' + encodeURIComponent(operation.operation_id); let saved = false; try { - storage.setItem(recordKey, JSON.stringify({ operation, queued_at: now() })); + storage.setItem(recordKey, JSON.stringify({ operation, queued_at: now() + operations.length })); knownOperationKeys.add(recordKey); saved = true; coordinator?.notify('today'); diff --git a/src/frontend_bundle.py b/src/frontend_bundle.py index d07c42b..05a9d76 100644 --- a/src/frontend_bundle.py +++ b/src/frontend_bundle.py @@ -38,7 +38,7 @@ FEATURE_SOURCES = { "static/today-rollover.js", "static/later-work.js", "static/later-picker.js", "static/drafts.js", "static/unfiled-captures.js", "static/unfiled-draft-sync.js", "static/assign-and-start.js", "static/filed-claim.js", "static/queue-today.js", "static/create-and-start.js", "static/draft-filing-session.js", "static/draft-capacity-dialog.js", "static/work-selection.js", - "static/today-work.js", "static/pick-work.js", "static/batch-find-work.js", + "static/today-work.js", "static/today-sync.js", "static/pick-work.js", "static/batch-find-work.js", "static/search-batch-plan.js", "static/mention-composer.js", "static/issue-evidence-review.js", "static/issue-evidence-editor.js", "static/issue-attachment.js", "static/checklist-conflict.js", "static/issue-outbox.js", "static/authored-outbox.js", "static/issue-sheet.js", "static/mobile-issue-detail-nav.js", "static/issue-filing-review.js", "static/issue-filing-receipt.js", ), diff --git a/tests/test_today_sync.py b/tests/test_today_sync.py index 8457cdf..a6f0ee6 100644 --- a/tests/test_today_sync.py +++ b/tests/test_today_sync.py @@ -83,6 +83,31 @@ sync.enqueue('add', 'issue:r:1:'); } +def test_operations_queued_in_the_same_millisecond_preserve_enqueue_order(): + script = f""" +const createTodaySync = require({json.dumps(str(TODAY_SYNC))}); +const values = new Map(); +const storage = {{ + get length() {{ return values.size; }}, key: index => [...values.keys()][index] || null, + getItem: key => values.get(key) || null, + setItem: (key, value) => values.set(key, value), removeItem: key => values.delete(key), +}}; +const operationIds = ['z-add-first', 'a-move-second']; +const sync = createTodaySync({{ + storage, getLogin: () => 'timmy', now: () => 1000, + createOperationId: () => operationIds.shift(), + fetchJson: async () => ({{revision: 0, ids: []}}), +}}); +sync.enqueue('add', 'issue:r:1:'); +sync.enqueue('move', 'issue:r:1:', 'up'); +process.stdout.write(JSON.stringify(sync.pending().map(operation => operation.operation_id))); +""" + + assert json.loads(subprocess.run( + ["node", "-e", script], check=True, capture_output=True, text=True + ).stdout) == ["z-add-first", "a-move-second"] + + def test_today_capacity_configuration_syncs_offline_and_adopts_remote_plan(): script = f""" const createTodaySync = require({json.dumps(str(TODAY_SYNC))});