@ttt-productions/notification-core 0.4.9 → 0.4.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationList.d.ts","sourceRoot":"","sources":["../../../src/react/components/NotificationList.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAmB,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE7E;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,MAAM,EACN,QAAQ,EACR,mBAAmB,EACnB,SAAS,EACT,YAAY,EACZ,UAAU,EACV,eAAe,EACf,SAAS,GACV,EAAE,qBAAqB,2CA8HvB"}
1
+ {"version":3,"file":"NotificationList.d.ts","sourceRoot":"","sources":["../../../src/react/components/NotificationList.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAmB,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE7E;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,MAAM,EACN,QAAQ,EACR,mBAAmB,EACnB,SAAS,EACT,YAAY,EACZ,UAAU,EACV,eAAe,EACf,SAAS,GACV,EAAE,qBAAqB,2CAwHvB"}
@@ -5,7 +5,6 @@ import { Badge, Button, Separator } from '@ttt-productions/ui-core/react';
5
5
  import { useActiveNotifications } from '../hooks/useActiveNotifications.js';
6
6
  import { useArchiveNotification } from '../hooks/useArchiveNotification.js';
7
7
  import { useArchiveAllNotifications } from '../hooks/useArchiveAllNotifications.js';
8
- import { useUnreadCount } from '../hooks/useUnreadCount.js';
9
8
  import { NotificationEmptyState } from './NotificationEmptyState.js';
10
9
  import { formatRelativeTime } from './relative-time.js';
11
10
  /**
@@ -18,12 +17,6 @@ export function NotificationList({ config, userId, category, onNotificationClick
18
17
  category,
19
18
  refetchInterval,
20
19
  });
21
- const { count: unreadCount } = useUnreadCount({
22
- config,
23
- userId,
24
- category,
25
- refetchInterval,
26
- });
27
20
  const archiveMutation = useArchiveNotification({
28
21
  userId,
29
22
  category,
@@ -56,11 +49,12 @@ export function NotificationList({ config, userId, category, onNotificationClick
56
49
  const typeConfig = config.types[type];
57
50
  return typeConfig?.icon ?? '🔔';
58
51
  }, [config]);
59
- return (_jsxs("div", { className: "ntf-list", children: [_jsxs("div", { className: "ntf-list-header", children: [_jsx("span", { className: "ntf-list-header-title", children: "Notifications" }), unreadCount > 0 && (_jsx(Button, { variant: "ghost", size: "sm", onClick: handleClearAll, disabled: archiveAllMutation.isPending, children: archiveAllMutation.isPending ? 'Clearing...' : 'Clear All' }))] }), _jsx(Separator, {}), isLoading ? (_jsx("div", { className: "ntf-loading", children: "Loading..." })) : !notifications || notifications.length === 0 ? (_jsx(NotificationEmptyState, { text: emptyText })) : (_jsxs(_Fragment, { children: [notifications.map((notification) => (_jsxs("div", { className: "ntf-item", role: "button", tabIndex: 0, onClick: () => handleNotificationClick(notification), onKeyDown: (e) => {
60
- if (e.key === 'Enter' || e.key === ' ') {
61
- e.preventDefault();
62
- handleNotificationClick(notification);
63
- }
64
- }, children: [_jsx("div", { className: "ntf-item-icon", children: getTypeIcon(notification.type) }), _jsxs("div", { className: "ntf-item-content", children: [_jsx("div", { className: "ntf-item-title", children: notification.title }), _jsx("div", { className: "ntf-item-message", children: notification.message }), _jsx("div", { className: "ntf-item-timestamp", children: formatRelativeTime(notification.updatedAt) })] }), notification.count > 1 && (_jsx("div", { className: "ntf-item-count", children: _jsxs(Badge, { variant: "secondary", children: ["\u00D7", notification.count] }) }))] }, notification.id))), hasNextPage && (_jsx("div", { className: "ntf-list-footer", children: _jsx(Button, { variant: "ghost", size: "sm", onClick: nextPage, children: "Load more" }) }))] }))] }));
52
+ const hasNotifications = !!notifications && notifications.length > 0;
53
+ return (_jsxs("div", { className: "ntf-list", children: [_jsx("div", { className: "ntf-list-header", children: _jsx(Button, { variant: "ghost", size: "sm", onClick: handleClearAll, disabled: !hasNotifications || archiveAllMutation.isPending, children: archiveAllMutation.isPending ? 'Clearing...' : 'Clear All' }) }), _jsx(Separator, {}), _jsx("div", { className: "ntf-list-body", children: isLoading ? (_jsx("div", { className: "ntf-loading", children: "Loading..." })) : !notifications || notifications.length === 0 ? (_jsx(NotificationEmptyState, { text: emptyText })) : (_jsxs(_Fragment, { children: [notifications.map((notification) => (_jsxs("div", { className: "ntf-item", role: "button", tabIndex: 0, onClick: () => handleNotificationClick(notification), onKeyDown: (e) => {
54
+ if (e.key === 'Enter' || e.key === ' ') {
55
+ e.preventDefault();
56
+ handleNotificationClick(notification);
57
+ }
58
+ }, children: [_jsx("div", { className: "ntf-item-icon", children: getTypeIcon(notification.type) }), _jsxs("div", { className: "ntf-item-content", children: [_jsx("div", { className: "ntf-item-title", children: notification.title }), _jsx("div", { className: "ntf-item-message", children: notification.message }), _jsx("div", { className: "ntf-item-timestamp", children: formatRelativeTime(notification.updatedAt) })] }), notification.count > 1 && (_jsx("div", { className: "ntf-item-count", children: _jsxs(Badge, { variant: "secondary", children: ["\u00D7", notification.count] }) }))] }, notification.id))), hasNextPage && (_jsx("div", { className: "ntf-list-footer", children: _jsx(Button, { variant: "ghost", size: "sm", onClick: nextPage, children: "Load more" }) }))] })) })] }));
65
59
  }
66
60
  //# sourceMappingURL=NotificationList.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationList.js","sourceRoot":"","sources":["../../../src/react/components/NotificationList.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"NotificationList.js","sourceRoot":"","sources":["../../../src/react/components/NotificationList.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Deterministic active-notification document IDs.
3
+ *
4
+ * The active doc for a given dedup scope always lives at the same ID, so
5
+ * concurrent writers (real-time sends racing each other or the batch
6
+ * materializer) converge on one document inside a transaction instead of
7
+ * racing a query-then-write. The ID hashes the same fields the dedup lookup
8
+ * used to filter on: category, audience scope, and dedupKey.
9
+ */
10
+ /**
11
+ * Build the deterministic doc ID for an active notification.
12
+ *
13
+ * Personal notifications scope per recipient (a fan-out to many users must
14
+ * never collapse into one recipient's doc); shared notifications are
15
+ * intentionally a single doc for the whole audience.
16
+ */
17
+ export declare function buildActiveNotificationDocId(params: {
18
+ category: string;
19
+ audienceType: 'personal' | 'shared';
20
+ targetUserId: string | null | undefined;
21
+ dedupKey: string;
22
+ }): string;
23
+ //# sourceMappingURL=activeNotificationId.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activeNotificationId.d.ts","sourceRoot":"","sources":["../../src/server/activeNotificationId.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,UAAU,GAAG,QAAQ,CAAC;IACpC,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,MAAM,CAOT"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activeNotificationId.js","sourceRoot":"","sources":["../../src/server/activeNotificationId.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;;;GAMG;AACH,MAAM,UAAU,4BAA4B,CAAC,MAK5C;IACC,MAAM,KAAK,GACT,MAAM,CAAC,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,MAAM,CAAC,YAAY,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC1F,OAAO,UAAU,CAAC,QAAQ,CAAC;SACxB,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,IAAI,KAAK,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;SACxD,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAClB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"createNotificationHelper.d.ts","sourceRoot":"","sources":["../../src/server/createNotificationHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EACV,eAAe,EAEf,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAOpB;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,wBAAwB,CACtC,EAAE,EAAE,eAAe,EACnB,MAAM,EAAE,wBAAwB,GAC/B,kBAAkB,CA6IpB"}
1
+ {"version":3,"file":"createNotificationHelper.d.ts","sourceRoot":"","sources":["../../src/server/createNotificationHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EACV,eAAe,EAEf,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAQpB;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,wBAAwB,CACtC,EAAE,EAAE,eAAe,EACnB,MAAM,EAAE,wBAAwB,GAC/B,kBAAkB,CAkJpB"}
@@ -2,6 +2,7 @@
2
2
  * Factory that creates the notification sending helper.
3
3
  * This is THE single entry point for all notification creation in any app.
4
4
  */
5
+ import { buildActiveNotificationDocId } from './activeNotificationId.js';
5
6
  const DEFAULT_COUNT_CAP = 5000;
6
7
  const DEFAULT_ACTOR_CAP = 5;
7
8
  /** Firestore hard limit on writes per batch. */
@@ -46,58 +47,61 @@ export function createNotificationHelper(db, config) {
46
47
  const dedupKey = typeConfig.dedupKeyPattern(metadata);
47
48
  const countCap = typeConfig.countCap ?? DEFAULT_COUNT_CAP;
48
49
  const actorCap = typeConfig.actorCap ?? DEFAULT_ACTOR_CAP;
49
- // Dedup check: query for existing doc with same dedupKey. Personal
50
- // notifications are scoped to the recipient so user B's notification never
51
- // re-lights user A's active doc that shares the same dedupKey; shared
52
- // notifications are intentionally a single doc for all admins.
53
- const activeCollection = db.collection(activePath);
54
- let existingQuery = activeCollection
55
- .where('dedupKey', '==', dedupKey)
56
- .where('category', '==', typeConfig.category);
57
- if (categoryConfig.audienceType === 'personal') {
58
- existingQuery = existingQuery.where('targetUserId', '==', targetUserId ?? null);
59
- }
60
- const existingSnap = await existingQuery.limit(1).get();
61
- if (!existingSnap.empty) {
62
- // Increment existing notification
63
- const existingDoc = existingSnap.docs[0];
64
- const existingData = existingDoc.data();
65
- const currentCount = existingData.count || 1;
66
- const currentActorIds = existingData.latestActorIds || [];
67
- // Cap actors (id-only newest first, deduped)
68
- const newActorIds = [actorId, ...currentActorIds.filter((id) => id !== actorId)].slice(0, actorCap);
69
- const newCount = Math.min(currentCount + 1, countCap);
70
- await existingDoc.ref.update({
71
- count: newCount,
72
- latestActorIds: newActorIds,
73
- message: typeConfig.messagePattern(metadata, newCount),
74
- // New activity on an existing notification re-lights the unread badge.
75
- seenAt: 0,
76
- updatedAt: Date.now(),
77
- });
78
- }
79
- else {
80
- // Create new notification
81
- const targetPath = resolveTargetPath(typeConfig.defaultTargetPath, metadata);
82
- const now = Date.now();
83
- const newDoc = {
84
- type,
85
- dedupKey,
86
- category: typeConfig.category,
87
- targetUserId: targetUserId ?? null,
88
- title: typeConfig.titlePattern(metadata),
89
- message: typeConfig.messagePattern(metadata, 1),
90
- count: 1,
91
- latestActorIds: [actorId],
92
- targetPath,
93
- metadata,
94
- // Active docs are created unseen so the unread count() predicate matches.
95
- seenAt: 0,
96
- createdAt: now,
97
- updatedAt: now,
98
- };
99
- await activeCollection.add(newDoc);
100
- }
50
+ // Dedup via deterministic doc ID: the active doc for this scope always
51
+ // lives at the same ID (hash of category + audience scope + dedupKey), so
52
+ // concurrent sends converge on one doc inside the transaction instead of
53
+ // racing a query-then-write. Personal notifications are scoped to the
54
+ // recipient so user B's notification never re-lights user A's active doc
55
+ // that shares the same dedupKey; shared notifications are intentionally a
56
+ // single doc for all admins.
57
+ const activeDocRef = db.collection(activePath).doc(buildActiveNotificationDocId({
58
+ category: typeConfig.category,
59
+ audienceType: categoryConfig.audienceType,
60
+ targetUserId: targetUserId ?? null,
61
+ dedupKey,
62
+ }));
63
+ await db.runTransaction(async (tx) => {
64
+ const existingSnap = await tx.get(activeDocRef);
65
+ if (existingSnap.exists) {
66
+ // Increment existing notification
67
+ const existingData = (existingSnap.data() ?? {});
68
+ const currentCount = existingData.count || 1;
69
+ const currentActorIds = existingData.latestActorIds || [];
70
+ // Cap actors (id-only newest first, deduped)
71
+ const newActorIds = [actorId, ...currentActorIds.filter((id) => id !== actorId)].slice(0, actorCap);
72
+ const newCount = Math.min(currentCount + 1, countCap);
73
+ tx.update(activeDocRef, {
74
+ count: newCount,
75
+ latestActorIds: newActorIds,
76
+ message: typeConfig.messagePattern(metadata, newCount),
77
+ // New activity on an existing notification re-lights the unread badge.
78
+ seenAt: 0,
79
+ updatedAt: Date.now(),
80
+ });
81
+ }
82
+ else {
83
+ // Create new notification
84
+ const targetPath = resolveTargetPath(typeConfig.defaultTargetPath, metadata);
85
+ const now = Date.now();
86
+ const newDoc = {
87
+ type,
88
+ dedupKey,
89
+ category: typeConfig.category,
90
+ targetUserId: targetUserId ?? null,
91
+ title: typeConfig.titlePattern(metadata),
92
+ message: typeConfig.messagePattern(metadata, 1),
93
+ count: 1,
94
+ latestActorIds: [actorId],
95
+ targetPath,
96
+ metadata,
97
+ // Active docs are created unseen so the unread count() predicate matches.
98
+ seenAt: 0,
99
+ createdAt: now,
100
+ updatedAt: now,
101
+ };
102
+ tx.set(activeDocRef, newDoc);
103
+ }
104
+ });
101
105
  }
102
106
  async function queueForBatch(input) {
103
107
  const pendingDoc = buildPendingDoc(input, Date.now());
@@ -1 +1 @@
1
- {"version":3,"file":"createNotificationHelper.js","sourceRoot":"","sources":["../../src/server/createNotificationHelper.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"createNotificationHelper.js","sourceRoot":"","sources":["../../src/server/createNotificationHelper.ts"],"names":[],"mappings":"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"}
@@ -3,5 +3,6 @@ export { processBatchHelper } from './processBatchHelper.js';
3
3
  export { archiveNotificationHelper, archiveAllNotificationsHelper, } from './archiveNotificationHelper.js';
4
4
  export { markSeenHelper } from './markSeenHelper.js';
5
5
  export { NotificationPermissionError } from './errors.js';
6
- export type { ServerFirestore, ServerCollectionRef, ServerQuery, ServerQuerySnapshot, ServerDocSnapshot, ServerDocRef, ServerWriteBatch, CreateNotificationInput, NotificationHelper, } from './types.js';
6
+ export { buildActiveNotificationDocId } from './activeNotificationId.js';
7
+ export type { ServerFirestore, ServerCollectionRef, ServerQuery, ServerQuerySnapshot, ServerDocSnapshot, ServerDocRef, ServerWriteBatch, ServerTransaction, CreateNotificationInput, NotificationHelper, } from './types.js';
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EACL,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAG1D,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EACL,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAGzE,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,YAAY,CAAC"}
@@ -4,4 +4,5 @@ export { processBatchHelper } from './processBatchHelper.js';
4
4
  export { archiveNotificationHelper, archiveAllNotificationsHelper, } from './archiveNotificationHelper.js';
5
5
  export { markSeenHelper } from './markSeenHelper.js';
6
6
  export { NotificationPermissionError } from './errors.js';
7
+ export { buildActiveNotificationDocId } from './activeNotificationId.js';
7
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EACL,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EACL,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"processBatchHelper.d.ts","sourceRoot":"","sources":["../../src/server/processBatchHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAuB,MAAM,aAAa,CAAC;AACjF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAOlD,UAAU,kBAAkB;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,eAAe,EACnB,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CA4L7B"}
1
+ {"version":3,"file":"processBatchHelper.d.ts","sourceRoot":"","sources":["../../src/server/processBatchHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAuB,MAAM,aAAa,CAAC;AACjF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAQlD,UAAU,kBAAkB;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,eAAe,EACnB,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CAiM7B"}
@@ -2,6 +2,7 @@
2
2
  * Batch processor helper — called by the app's scheduled Cloud Function.
3
3
  * Reads pending notifications, groups by dedupKey, creates/increments active docs.
4
4
  */
5
+ import { buildActiveNotificationDocId } from './activeNotificationId.js';
5
6
  const DEFAULT_COUNT_CAP = 5000;
6
7
  const DEFAULT_ACTOR_CAP = 5;
7
8
  const PROCESSING_BATCH_SIZE = 500;
@@ -79,14 +80,16 @@ export async function processBatchHelper(db, config) {
79
80
  });
80
81
  }
81
82
  }
82
- // Process each group: dedup check against active, create or increment.
83
- // Groups are processed in parallel. Each group's groupKey uniquely determines
84
- // a single active doc the active lookup filters on exactly the same
85
- // dedupKey + category (+ targetUserId for personal) that compose the groupKey —
86
- // so two distinct groups can never resolve to the same active doc and there is
87
- // no cross-group contention to guard with a transaction. The work per group is
88
- // independent I/O, so Promise.all turns N sequential round-trips into one
89
- // parallel wave, removing the timeout risk under high dedup-group counts.
83
+ // Process each group: create or increment the group's active doc.
84
+ // Each group's groupKey uniquely determines a single active doc — the doc ID
85
+ // is a deterministic hash of exactly the dedupKey + category (+ targetUserId
86
+ // for personal) that compose the groupKey — so two distinct groups can never
87
+ // resolve to the same active doc and there is no cross-group contention. The
88
+ // work per group is independent I/O, so Promise.all turns N sequential
89
+ // round-trips into one parallel wave, removing the timeout risk under high
90
+ // dedup-group counts. WITHIN a dedup scope, the transactional read-modify-write
91
+ // on the deterministic ID makes concurrent writers (a racing real-time send,
92
+ // or an overlapping batch run) converge on one doc with correct counts.
90
93
  const groupResults = await Promise.all(Array.from(groups.values()).map(async (group) => {
91
94
  const typeConfig = config.types[group.type];
92
95
  if (!typeConfig)
@@ -98,64 +101,65 @@ export async function processBatchHelper(db, config) {
98
101
  const dedupKey = typeConfig.dedupKeyPattern(group.metadata);
99
102
  const countCap = typeConfig.countCap ?? DEFAULT_COUNT_CAP;
100
103
  const actorCap = typeConfig.actorCap ?? DEFAULT_ACTOR_CAP;
101
- // Check for existing active notification. Personal notifications are
102
- // scoped to the recipient so different recipients never share an active
103
- // doc; shared notifications omit targetUserId by design.
104
- let existingQuery = db.collection(activePath)
105
- .where('dedupKey', '==', dedupKey)
106
- .where('category', '==', group.category);
107
- if (categoryConfig.audienceType === 'personal') {
108
- existingQuery = existingQuery.where('targetUserId', '==', group.targetUserId);
109
- }
110
- const existingSnap = await existingQuery.limit(1).get();
111
- if (!existingSnap.empty) {
112
- // Increment existing
113
- const existingDoc = existingSnap.docs[0];
114
- const existingData = existingDoc.data();
115
- const currentCount = existingData.count || 1;
116
- const currentActorIds = existingData.latestActorIds || [];
117
- // Merge actor ids (new first, deduped, capped)
118
- const newActorIds = group.actorIds.filter((id) => !currentActorIds.includes(id));
119
- const mergedActorIds = [
120
- ...newActorIds,
121
- ...currentActorIds,
122
- ].slice(0, actorCap);
123
- const newCount = Math.min(currentCount + group.count, countCap);
124
- await existingDoc.ref.update({
125
- count: newCount,
126
- latestActorIds: mergedActorIds,
127
- message: typeConfig.messagePattern(group.metadata, newCount),
128
- // New activity on an existing notification re-lights the unread badge.
129
- seenAt: 0,
130
- updatedAt: Date.now(),
131
- });
132
- return 'updated';
133
- }
134
- else {
135
- // Create new notification
136
- const targetPath = typeof typeConfig.defaultTargetPath === 'function'
137
- ? typeConfig.defaultTargetPath(group.metadata)
138
- : typeConfig.defaultTargetPath;
139
- const now = Date.now();
140
- const newDoc = {
141
- type: group.type,
142
- dedupKey,
143
- category: group.category,
144
- targetUserId: group.targetUserId,
145
- title: typeConfig.titlePattern(group.metadata),
146
- message: typeConfig.messagePattern(group.metadata, group.count),
147
- count: group.count,
148
- latestActorIds: group.actorIds.slice(0, actorCap),
149
- targetPath,
150
- metadata: group.metadata,
151
- // Active docs are created unseen so the unread count() predicate matches.
152
- seenAt: 0,
153
- createdAt: now,
154
- updatedAt: now,
155
- };
156
- await db.collection(activePath).add(newDoc);
157
- return 'created';
158
- }
104
+ // Personal notifications are scoped to the recipient so different
105
+ // recipients never share an active doc; shared notifications omit
106
+ // targetUserId by design.
107
+ const activeDocRef = db.collection(activePath).doc(buildActiveNotificationDocId({
108
+ category: group.category,
109
+ audienceType: categoryConfig.audienceType,
110
+ targetUserId: group.targetUserId,
111
+ dedupKey,
112
+ }));
113
+ return db.runTransaction(async (tx) => {
114
+ const existingSnap = await tx.get(activeDocRef);
115
+ if (existingSnap.exists) {
116
+ // Increment existing
117
+ const existingData = (existingSnap.data() ?? {});
118
+ const currentCount = existingData.count || 1;
119
+ const currentActorIds = existingData.latestActorIds || [];
120
+ // Merge actor ids (new first, deduped, capped)
121
+ const newActorIds = group.actorIds.filter((id) => !currentActorIds.includes(id));
122
+ const mergedActorIds = [
123
+ ...newActorIds,
124
+ ...currentActorIds,
125
+ ].slice(0, actorCap);
126
+ const newCount = Math.min(currentCount + group.count, countCap);
127
+ tx.update(activeDocRef, {
128
+ count: newCount,
129
+ latestActorIds: mergedActorIds,
130
+ message: typeConfig.messagePattern(group.metadata, newCount),
131
+ // New activity on an existing notification re-lights the unread badge.
132
+ seenAt: 0,
133
+ updatedAt: Date.now(),
134
+ });
135
+ return 'updated';
136
+ }
137
+ else {
138
+ // Create new notification
139
+ const targetPath = typeof typeConfig.defaultTargetPath === 'function'
140
+ ? typeConfig.defaultTargetPath(group.metadata)
141
+ : typeConfig.defaultTargetPath;
142
+ const now = Date.now();
143
+ const newDoc = {
144
+ type: group.type,
145
+ dedupKey,
146
+ category: group.category,
147
+ targetUserId: group.targetUserId,
148
+ title: typeConfig.titlePattern(group.metadata),
149
+ message: typeConfig.messagePattern(group.metadata, group.count),
150
+ count: group.count,
151
+ latestActorIds: group.actorIds.slice(0, actorCap),
152
+ targetPath,
153
+ metadata: group.metadata,
154
+ // Active docs are created unseen so the unread count() predicate matches.
155
+ seenAt: 0,
156
+ createdAt: now,
157
+ updatedAt: now,
158
+ };
159
+ tx.set(activeDocRef, newDoc);
160
+ return 'created';
161
+ }
162
+ });
159
163
  }));
160
164
  for (const r of groupResults) {
161
165
  if (r === 'created')
@@ -1 +1 @@
1
- {"version":3,"file":"processBatchHelper.js","sourceRoot":"","sources":["../../src/server/processBatchHelper.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"processBatchHelper.js","sourceRoot":"","sources":["../../src/server/processBatchHelper.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,15 @@ export interface ServerFirestore {
10
10
  collection(path: string): ServerCollectionRef;
11
11
  doc(path: string): ServerDocRef;
12
12
  batch(): ServerWriteBatch;
13
+ runTransaction<T>(updateFunction: (transaction: ServerTransaction) => Promise<T>): Promise<T>;
14
+ }
15
+ export interface ServerTransaction {
16
+ get(ref: ServerDocRef): Promise<ServerDocSnapshot>;
17
+ set(ref: ServerDocRef, data: Record<string, unknown>, options?: {
18
+ merge?: boolean;
19
+ }): ServerTransaction;
20
+ update(ref: ServerDocRef, data: Record<string, unknown>): ServerTransaction;
21
+ delete(ref: ServerDocRef): ServerTransaction;
13
22
  }
14
23
  export interface ServerCollectionRef {
15
24
  doc(id?: string): ServerDocRef;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttt-productions/notification-core",
3
- "version": "0.4.9",
3
+ "version": "0.4.10",
4
4
  "description": "Shared notification system for TTT Productions apps — active/history two-tier architecture with dedup, batch processing, and themed UI components",
5
5
  "repository": {
6
6
  "type": "git",
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "peerDependencies": {
41
41
  "@tanstack/react-query": ">=5.0.0",
42
- "@ttt-productions/query-core": "^0.8.6",
42
+ "@ttt-productions/query-core": "^0.8.8",
43
43
  "@ttt-productions/ui-core": "^0.6.4",
44
44
  "firebase": ">=10.0.0",
45
45
  "react": ">=18.0.0",
@@ -67,7 +67,7 @@
67
67
  },
68
68
  "devDependencies": {
69
69
  "@tanstack/react-query": "^5.0.0",
70
- "@ttt-productions/query-core": "^0.8.6",
70
+ "@ttt-productions/query-core": "^0.8.8",
71
71
  "@ttt-productions/ui-core": "^0.6.4",
72
72
  "@types/react": "^19.0.0",
73
73
  "@types/react-dom": "^19.0.0",
@@ -11,23 +11,23 @@
11
11
  display: flex;
12
12
  flex-direction: column;
13
13
  max-height: 24rem;
14
+ }
15
+
16
+ /* Header stays pinned; only the body scrolls. */
17
+ .ntf-list-body {
18
+ flex: 1;
19
+ min-height: 0;
14
20
  overflow-y: auto;
15
21
  }
16
22
 
17
23
  .ntf-list-header {
18
24
  display: flex;
19
25
  align-items: center;
20
- justify-content: space-between;
21
- padding: 0.75rem 1rem;
26
+ justify-content: flex-end;
27
+ padding: 0.25rem 0.5rem;
22
28
  border-bottom: 1px solid hsl(var(--border));
23
29
  }
24
30
 
25
- .ntf-list-header-title {
26
- font-weight: 600;
27
- font-size: 0.875rem;
28
- color: hsl(var(--foreground));
29
- }
30
-
31
31
  .ntf-list-footer {
32
32
  display: flex;
33
33
  align-items: center;