Files
iistwin/server/utils/pushSyncNeeded.ts

59 lines
2.3 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { storage } from '../storage';
import { webPushService } from '../services/web-push.service';
import { eventBus } from '../routes/shared';
const SYNC_PUSH_COOLDOWN_MS = 5 * 60 * 1000; // 5 minutes
const lastPushByOrganization = new Map<number, number>();
/**
* Sends a silent web-push to subscribed devices in the organization
* telling them to run an offline sync (delta sync) because task data changed.
*
* The push has no visible notification; the Service Worker catches the
* `SYNC_NEEDED` payload and registers a background sync.
*
* Throttled to one push per organization per cooldown window, and skipped
* for users that currently have an active SSE connection (their open app
* will sync via SSE immediately).
*/
export async function pushSyncNeeded(organizationId: number): Promise<void> {
try {
const now = Date.now();
const lastPush = lastPushByOrganization.get(organizationId);
if (lastPush != null && now - lastPush < SYNC_PUSH_COOLDOWN_MS) {
console.log(`[WebPush] pushSyncNeeded skipped for org ${organizationId}: cooldown active`);
return;
}
const subscriptions = await storage.getWebPushSubscriptionsByOrganization(organizationId);
if (subscriptions.length === 0) return;
let sent = 0;
let skipped = 0;
for (const sub of subscriptions) {
try {
// Если у пользователя открыто приложение с активным SSE, пуш не нужен —
// он и так получит task_updated и запустит синхронизацию.
if (eventBus.isUserConnected(sub.userId, organizationId)) {
skipped++;
continue;
}
const subscription = JSON.parse(sub.subscription);
const success = await webPushService.sendNotification(subscription, {
type: 'SYNC_NEEDED',
data: { organizationId },
});
if (success) sent++;
} catch (err) {
console.error('[WebPush] pushSyncNeeded single subscription error:', err);
}
}
lastPushByOrganization.set(organizationId, now);
console.log(`[WebPush] pushSyncNeeded org=${organizationId} sent=${sent} skipped_sse=${skipped}/${subscriptions.length}`);
} catch (err) {
console.error('[WebPush] pushSyncNeeded error:', err);
}
}