diff --git a/scripts/verify-mindspace-page-sync-guards.mjs b/scripts/verify-mindspace-page-sync-guards.mjs index 36f65f1..d1129ea 100644 --- a/scripts/verify-mindspace-page-sync-guards.mjs +++ b/scripts/verify-mindspace-page-sync-guards.mjs @@ -20,7 +20,18 @@ const contractSource = read('mindspace-server-adapter-contract.mjs'); assertIncludes( 'server.mjs syncUserGeneratedPages', serverSource, - 'await mindSpacePageSync.syncUserGeneratedPages(userId);', + 'mindSpacePageSync.syncUserGeneratedPages(userId', +); +assertIncludes( + 'server.mjs list page sync bypasses full delivery', + serverSource, + 'listSync = false', +); +const pageCoreRoutesSource = read('server/portal-mindspace-page-core-routes.mjs'); +assertIncludes( + 'portal page list background sync', + pageCoreRoutesSource, + 'syncUserGeneratedPages(userId, { listSync: true })', ); if (serverSource.includes("mindSpaceServerRuntime.adapterKind === 'remote'")) { throw new Error( diff --git a/server.mjs b/server.mjs index f836c9d..c95793b 100644 --- a/server.mjs +++ b/server.mjs @@ -1292,7 +1292,7 @@ async function listSessionPublicHtmlRelativePaths(userId, sessionId, { sinceMs = async function syncUserGeneratedPages( userId, - { sessionId = null, sinceMs = null, onlyRelativePaths = null } = {}, + { sessionId = null, sinceMs = null, onlyRelativePaths = null, listSync = false } = {}, ) { if (!userId) return; // Agent-run/Finish delivery must stay scoped to the current conversation. @@ -1330,11 +1330,13 @@ async function syncUserGeneratedPages( : sessionId ? (discoveredRelativePaths?.length ? discoveredRelativePaths : recentWorkspaceRelativePaths) : null; - if (workspacePageDeliver?.syncAndDeliver) { + if (!listSync && workspacePageDeliver?.syncAndDeliver) { return await workspacePageDeliver.syncAndDeliver(userId, { pageDataRelativePaths }); } if (!mindSpacePageSync) return; - return await mindSpacePageSync.syncUserGeneratedPages(userId); + return await mindSpacePageSync.syncUserGeneratedPages(userId, { + onlyRelativePaths: pageDataRelativePaths, + }); } async function resolveChatSaveBundle(user, h5Root, input = {}) { diff --git a/server/portal-mindspace-page-core-routes.mjs b/server/portal-mindspace-page-core-routes.mjs index 3f5fde4..f6adba6 100644 --- a/server/portal-mindspace-page-core-routes.mjs +++ b/server/portal-mindspace-page-core-routes.mjs @@ -46,7 +46,7 @@ export function createMindSpacePageListSyncScheduler({ lastStartedAtByUser.set(userId, currentTime); const task = Promise.resolve() - .then(() => syncUserGeneratedPages(userId)) + .then(() => syncUserGeneratedPages(userId, { listSync: true })) .catch((error) => { logger?.warn?.( `[MindSpace] background page list sync failed for user ${userId}:`, diff --git a/server/portal-mindspace-page-core-routes.test.mjs b/server/portal-mindspace-page-core-routes.test.mjs index 48c1f0a..6548dc3 100644 --- a/server/portal-mindspace-page-core-routes.test.mjs +++ b/server/portal-mindspace-page-core-routes.test.mjs @@ -230,8 +230,8 @@ test('page list background sync coalesces in-flight and throttled requests', asy const scheduler = createMindSpacePageListSyncScheduler({ now: () => currentTime, minIntervalMs: 30_000, - syncUserGeneratedPages(userId) { - calls.push(userId); + syncUserGeneratedPages(userId, options) { + calls.push({ userId, options }); return new Promise((resolve) => { resolvers.push(resolve); }); @@ -242,19 +242,22 @@ test('page list background sync coalesces in-flight and throttled requests', asy const second = scheduler('user-1'); assert.equal(first, second); await Promise.resolve(); - assert.deepEqual(calls, ['user-1']); + assert.deepEqual(calls, [{ userId: 'user-1', options: { listSync: true } }]); resolvers.shift()?.({ created: 0, updated: 0, skipped: 0 }); await first; currentTime += 1_000; assert.equal(scheduler('user-1'), null); - assert.deepEqual(calls, ['user-1']); + assert.deepEqual(calls, [{ userId: 'user-1', options: { listSync: true } }]); currentTime += 30_000; const third = scheduler('user-1'); await Promise.resolve(); - assert.deepEqual(calls, ['user-1', 'user-1']); + assert.deepEqual(calls, [ + { userId: 'user-1', options: { listSync: true } }, + { userId: 'user-1', options: { listSync: true } }, + ]); resolvers.shift()?.({ created: 0, updated: 0, skipped: 0 }); await third; });