From 37e919f43f5e1c7d1002757b4692e725369f2e9f Mon Sep 17 00:00:00 2001 From: timmy Date: Wed, 19 Aug 2026 21:52:50 +0000 Subject: [PATCH] fix: preserve first-task completion delivery --- frontend/mobile-first-task.js | 1 + frontend/today-sync.js | 10 ++-------- tests/test_mobile_first_task.py | 2 +- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/frontend/mobile-first-task.js b/frontend/mobile-first-task.js index 3d41561..a96aece 100644 --- a/frontend/mobile-first-task.js +++ b/frontend/mobile-first-task.js @@ -102,6 +102,7 @@ function completeOutcome() { if (state() !== 'coaching') return false; store('complete'); + options.eventTarget?.dispatchEvent?.(new CustomEvent('stackchain:first-task-complete')); renderCoach(); if (options.receipt) { options.receipt.hidden = false; diff --git a/frontend/today-sync.js b/frontend/today-sync.js index 7d97630..a6497de 100644 --- a/frontend/today-sync.js +++ b/frontend/today-sync.js @@ -13,7 +13,6 @@ function createTodaySync({ storage, getLogin, fetchJson, onRemoteIds, onRemotePl let discardedCount = 0; let recoveryNotice = { discarded: 0, until: 0 }; const knownOperationKeys = new Set(); - const operationRecordKeys = new Map(); function cancelRetry() { if (retryTimer !== null) clearTimer?.(retryTimer); @@ -138,7 +137,6 @@ function createTodaySync({ storage, getLogin, fetchJson, onRemoteIds, onRemotePl ['add', 'remove', 'move', 'configure', 'rollover', 'activate'].includes(operation.action) && typeof operation.item_id === 'string') && Number.isFinite(Number(record.queued_at)); if (valid) operations.forEach((operation, index) => { - operationRecordKeys.set(operation.operation_id, recordKey); records.push({operation, queued_at:Number(record.queued_at) + index / 1000, recordKey}); }); else { @@ -175,12 +173,10 @@ function createTodaySync({ storage, getLogin, fetchJson, onRemoteIds, onRemotePl function removeOperation(operationId) { const storageKey = key(); if (!storageKey || !storage) return false; - const recordKey = operationRecordKeys.get(operationId) || - storageKey + '.operation.' + encodeURIComponent(operationId); + const recordKey = storageKey + '.operation.' + encodeURIComponent(operationId); try { storage.removeItem(recordKey); knownOperationKeys.delete(recordKey); - operationRecordKeys.delete(operationId); return true; } catch (_error) { return false; @@ -197,13 +193,11 @@ function createTodaySync({ storage, getLogin, fetchJson, onRemoteIds, onRemotePl const storageKey = key(); if (!storageKey || !storage) return false; const batched = operations.length > 1; - const recordKey = storageKey + '.operation.' + (batched ? 'batch-' : '') + - encodeURIComponent(operations[0].operation_id); + const recordKey = storageKey + '.operation.' + encodeURIComponent(operations[0].operation_id); try { storage.setItem(recordKey, JSON.stringify(batched ? {operations, queued_at:queuedAt} : {operation:operations[0], queued_at:queuedAt})); knownOperationKeys.add(recordKey); - operations.forEach(operation => operationRecordKeys.set(operation.operation_id, recordKey)); coordinator?.notify('today'); onStatus?.('pending'); return true; diff --git a/tests/test_mobile_first_task.py b/tests/test_mobile_first_task.py index fefa5d8..a071bad 100644 --- a/tests/test_mobile_first_task.py +++ b/tests/test_mobile_first_task.py @@ -214,7 +214,7 @@ process.stdout.write(JSON.stringify({before,globalProbe,completed,stored:values. "globalProbe": True, "completed": True, "stored": "complete", - "dispatched": 0, + "dispatched": 1, }