@ttt-productions/notification-core 0.4.2 → 0.4.4
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.
- package/README.md +21 -4
- package/dist/react/components/NotificationList.d.ts +1 -1
- package/dist/react/components/NotificationList.d.ts.map +1 -1
- package/dist/react/components/NotificationList.js +7 -20
- package/dist/react/components/NotificationList.js.map +1 -1
- package/dist/react/hooks/useArchiveAllNotifications.d.ts +10 -12
- package/dist/react/hooks/useArchiveAllNotifications.d.ts.map +1 -1
- package/dist/react/hooks/useArchiveAllNotifications.js +10 -58
- package/dist/react/hooks/useArchiveAllNotifications.js.map +1 -1
- package/dist/react/hooks/useArchiveNotification.d.ts +12 -11
- package/dist/react/hooks/useArchiveNotification.d.ts.map +1 -1
- package/dist/react/hooks/useArchiveNotification.js +12 -39
- package/dist/react/hooks/useArchiveNotification.js.map +1 -1
- package/dist/react/hooks/useUnreadCount.d.ts +30 -21
- package/dist/react/hooks/useUnreadCount.d.ts.map +1 -1
- package/dist/react/hooks/useUnreadCount.js +29 -15
- package/dist/react/hooks/useUnreadCount.js.map +1 -1
- package/dist/server/archiveNotificationHelper.d.ts +14 -3
- package/dist/server/archiveNotificationHelper.d.ts.map +1 -1
- package/dist/server/archiveNotificationHelper.js +36 -7
- package/dist/server/archiveNotificationHelper.js.map +1 -1
- package/dist/server/createNotificationHelper.d.ts.map +1 -1
- package/dist/server/createNotificationHelper.js +41 -9
- package/dist/server/createNotificationHelper.js.map +1 -1
- package/dist/server/errors.d.ts +13 -0
- package/dist/server/errors.d.ts.map +1 -0
- package/dist/server/errors.js +19 -0
- package/dist/server/errors.js.map +1 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/markSeenHelper.d.ts +17 -0
- package/dist/server/markSeenHelper.d.ts.map +1 -0
- package/dist/server/markSeenHelper.js +29 -0
- package/dist/server/markSeenHelper.js.map +1 -0
- package/dist/server/processBatchHelper.d.ts.map +1 -1
- package/dist/server/processBatchHelper.js +23 -6
- package/dist/server/processBatchHelper.js.map +1 -1
- package/dist/server/types.d.ts +6 -0
- package/dist/server/types.d.ts.map +1 -1
- package/dist/types.d.ts +39 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archiveNotificationHelper.d.ts","sourceRoot":"","sources":["../../src/server/archiveNotificationHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,wBAAwB,EACxB,YAAY,EACb,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"archiveNotificationHelper.d.ts","sourceRoot":"","sources":["../../src/server/archiveNotificationHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,wBAAwB,EACxB,YAAY,EACb,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGlD,UAAU,YAAY;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,SAAS,EAAE,MAAM,CAAC;IAClB,2FAA2F;IAC3F,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,YAAY,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,eAAe;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,aAAa;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AA+BD;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,EAAE,EAAE,eAAe,EACnB,MAAM,EAAE,wBAAwB,EAChC,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,aAAa,CAAC,CAsCxB;AAED;;GAEG;AACH,wBAAsB,6BAA6B,CACjD,EAAE,EAAE,eAAe,EACnB,MAAM,EAAE,wBAAwB,EAChC,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,aAAa,CAAC,CA8DxB"}
|
|
@@ -2,27 +2,50 @@
|
|
|
2
2
|
* Archive notification helper — used by callable Cloud Functions.
|
|
3
3
|
* Moves active → history with ArchivalInfo, deletes from active.
|
|
4
4
|
*/
|
|
5
|
+
import { NotificationPermissionError } from './errors.js';
|
|
5
6
|
/**
|
|
6
|
-
*
|
|
7
|
+
* Assert the caller may archive a notification in this category.
|
|
8
|
+
*
|
|
9
|
+
* - personal: the active doc's `targetUserId` must equal `callerUid`.
|
|
10
|
+
* - shared: the category must be `shared` and the caller must be an admin.
|
|
11
|
+
*
|
|
12
|
+
* Throws on mismatch so the callable surfaces a permission error.
|
|
13
|
+
*/
|
|
14
|
+
function assertCanArchive(audienceType, activeData, callerUid, callerIsAdmin) {
|
|
15
|
+
if (audienceType === 'shared') {
|
|
16
|
+
if (!callerIsAdmin) {
|
|
17
|
+
throw new NotificationPermissionError('[notification-core] Permission denied: shared notifications can only be archived by an admin');
|
|
18
|
+
}
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (activeData.targetUserId !== callerUid) {
|
|
22
|
+
throw new NotificationPermissionError('[notification-core] Permission denied: caller does not own this notification');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Archive a single notification on the server side. Verifies ownership before
|
|
27
|
+
* the active → history move and persists the app-supplied `expireAt`.
|
|
7
28
|
*/
|
|
8
29
|
export async function archiveNotificationHelper(db, config, input) {
|
|
9
|
-
const { notificationId, category,
|
|
30
|
+
const { notificationId, category, callerUid, callerIsAdmin, archivalInfo, expireAt } = input;
|
|
10
31
|
const categoryConfig = config.categories[category];
|
|
11
32
|
if (!categoryConfig) {
|
|
12
33
|
throw new Error(`[notification-core] Unknown category: ${category}`);
|
|
13
34
|
}
|
|
14
35
|
const activePath = categoryConfig.activePath;
|
|
15
|
-
const historyPath = categoryConfig.historyPath(
|
|
36
|
+
const historyPath = categoryConfig.historyPath(callerUid);
|
|
16
37
|
const activeRef = db.doc(`${activePath}/${notificationId}`);
|
|
17
38
|
const activeSnap = await activeRef.get();
|
|
18
39
|
if (!activeSnap.exists) {
|
|
19
40
|
return { success: true, archived: 0 };
|
|
20
41
|
}
|
|
21
42
|
const activeData = activeSnap.data();
|
|
43
|
+
assertCanArchive(categoryConfig.audienceType, activeData, callerUid, callerIsAdmin);
|
|
22
44
|
const historyDoc = {
|
|
23
45
|
...activeData,
|
|
24
46
|
id: notificationId,
|
|
25
47
|
archival: archivalInfo,
|
|
48
|
+
...(expireAt !== undefined ? { expireAt } : {}),
|
|
26
49
|
...(categoryConfig.audienceType === 'shared'
|
|
27
50
|
? { handledBy: archivalInfo.archivedBy }
|
|
28
51
|
: {}),
|
|
@@ -38,20 +61,25 @@ export async function archiveNotificationHelper(db, config, input) {
|
|
|
38
61
|
* Archive all active notifications for a user/category on the server side.
|
|
39
62
|
*/
|
|
40
63
|
export async function archiveAllNotificationsHelper(db, config, input) {
|
|
41
|
-
const { category,
|
|
64
|
+
const { category, callerUid, callerIsAdmin, archivalInfo, expireAt } = input;
|
|
42
65
|
const categoryConfig = config.categories[category];
|
|
43
66
|
if (!categoryConfig) {
|
|
44
67
|
throw new Error(`[notification-core] Unknown category: ${category}`);
|
|
45
68
|
}
|
|
46
|
-
const activePath = categoryConfig.activePath;
|
|
47
|
-
const historyPath = categoryConfig.historyPath(userId);
|
|
48
69
|
const isPersonal = categoryConfig.audienceType === 'personal';
|
|
70
|
+
// Shared archive-all is an admin-only bulk action; personal stays bounded to
|
|
71
|
+
// the caller by the `targetUserId == callerUid` query filter below.
|
|
72
|
+
if (!isPersonal && !callerIsAdmin) {
|
|
73
|
+
throw new NotificationPermissionError('[notification-core] Permission denied: shared notifications can only be archived by an admin');
|
|
74
|
+
}
|
|
75
|
+
const activePath = categoryConfig.activePath;
|
|
76
|
+
const historyPath = categoryConfig.historyPath(callerUid);
|
|
49
77
|
let totalArchived = 0;
|
|
50
78
|
let hasMore = true;
|
|
51
79
|
while (hasMore) {
|
|
52
80
|
const baseQuery = db.collection(activePath);
|
|
53
81
|
const q = isPersonal
|
|
54
|
-
? baseQuery.where('targetUserId', '==',
|
|
82
|
+
? baseQuery.where('targetUserId', '==', callerUid).orderBy('updatedAt', 'desc').limit(50)
|
|
55
83
|
: baseQuery.orderBy('updatedAt', 'desc').limit(50);
|
|
56
84
|
const snapshot = await q.get();
|
|
57
85
|
if (snapshot.empty) {
|
|
@@ -66,6 +94,7 @@ export async function archiveAllNotificationsHelper(db, config, input) {
|
|
|
66
94
|
...data,
|
|
67
95
|
id: docSnap.id,
|
|
68
96
|
archival: archivalInfo,
|
|
97
|
+
...(expireAt !== undefined ? { expireAt } : {}),
|
|
69
98
|
...(categoryConfig.audienceType === 'shared'
|
|
70
99
|
? { handledBy: archivalInfo.archivedBy }
|
|
71
100
|
: {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archiveNotificationHelper.js","sourceRoot":"","sources":["../../src/server/archiveNotificationHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"archiveNotificationHelper.js","sourceRoot":"","sources":["../../src/server/archiveNotificationHelper.ts"],"names":[],"mappings":"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"}
|
|
@@ -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;
|
|
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"}
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
const DEFAULT_COUNT_CAP = 5000;
|
|
6
6
|
const DEFAULT_ACTOR_CAP = 5;
|
|
7
|
+
/** Firestore hard limit on writes per batch. */
|
|
8
|
+
const MAX_BATCH_WRITES = 500;
|
|
7
9
|
/**
|
|
8
10
|
* Create a notification helper bound to a Firestore instance and config.
|
|
9
11
|
*
|
|
@@ -44,13 +46,18 @@ export function createNotificationHelper(db, config) {
|
|
|
44
46
|
const dedupKey = typeConfig.dedupKeyPattern(metadata);
|
|
45
47
|
const countCap = typeConfig.countCap ?? DEFAULT_COUNT_CAP;
|
|
46
48
|
const actorCap = typeConfig.actorCap ?? DEFAULT_ACTOR_CAP;
|
|
47
|
-
// Dedup check: query for existing doc with same dedupKey
|
|
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.
|
|
48
53
|
const activeCollection = db.collection(activePath);
|
|
49
|
-
|
|
54
|
+
let existingQuery = activeCollection
|
|
50
55
|
.where('dedupKey', '==', dedupKey)
|
|
51
|
-
.where('category', '==', typeConfig.category)
|
|
52
|
-
|
|
53
|
-
|
|
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();
|
|
54
61
|
if (!existingSnap.empty) {
|
|
55
62
|
// Increment existing notification
|
|
56
63
|
const existingDoc = existingSnap.docs[0];
|
|
@@ -64,6 +71,8 @@ export function createNotificationHelper(db, config) {
|
|
|
64
71
|
count: newCount,
|
|
65
72
|
latestActorIds: newActorIds,
|
|
66
73
|
message: typeConfig.messagePattern(metadata, newCount),
|
|
74
|
+
// New activity on an existing notification re-lights the unread badge.
|
|
75
|
+
seenAt: 0,
|
|
67
76
|
updatedAt: Date.now(),
|
|
68
77
|
});
|
|
69
78
|
}
|
|
@@ -82,6 +91,8 @@ export function createNotificationHelper(db, config) {
|
|
|
82
91
|
latestActorIds: [actorId],
|
|
83
92
|
targetPath,
|
|
84
93
|
metadata,
|
|
94
|
+
// Active docs are created unseen so the unread count() predicate matches.
|
|
95
|
+
seenAt: 0,
|
|
85
96
|
createdAt: now,
|
|
86
97
|
updatedAt: now,
|
|
87
98
|
};
|
|
@@ -89,17 +100,38 @@ export function createNotificationHelper(db, config) {
|
|
|
89
100
|
}
|
|
90
101
|
}
|
|
91
102
|
async function queueForBatch(input) {
|
|
103
|
+
const pendingDoc = buildPendingDoc(input, Date.now());
|
|
104
|
+
await db.collection(pendingPath).add(pendingDoc);
|
|
105
|
+
}
|
|
106
|
+
function buildPendingDoc(input, now) {
|
|
92
107
|
const { type, actorId, targetUserId, metadata } = input;
|
|
93
108
|
const { typeConfig } = getTypeConfig(type);
|
|
94
|
-
|
|
109
|
+
// Pending docs carry NO seenAt — seenAt lives only on active docs, set by
|
|
110
|
+
// the materializer (sendRealTime / processBatchHelper).
|
|
111
|
+
return {
|
|
95
112
|
type,
|
|
96
113
|
category: typeConfig.category,
|
|
97
114
|
targetUserId: targetUserId ?? null,
|
|
98
115
|
actorId,
|
|
99
116
|
metadata,
|
|
100
|
-
createdAt:
|
|
117
|
+
createdAt: now,
|
|
101
118
|
};
|
|
102
|
-
|
|
119
|
+
}
|
|
120
|
+
async function queueManyForBatch(inputs) {
|
|
121
|
+
if (inputs.length === 0)
|
|
122
|
+
return;
|
|
123
|
+
const pendingCollection = db.collection(pendingPath);
|
|
124
|
+
const now = Date.now();
|
|
125
|
+
// Write in ≤500-write chunks (the Firestore batch limit).
|
|
126
|
+
for (let i = 0; i < inputs.length; i += MAX_BATCH_WRITES) {
|
|
127
|
+
const chunk = inputs.slice(i, i + MAX_BATCH_WRITES);
|
|
128
|
+
const batch = db.batch();
|
|
129
|
+
for (const input of chunk) {
|
|
130
|
+
const ref = pendingCollection.doc();
|
|
131
|
+
batch.set(ref, buildPendingDoc(input, now));
|
|
132
|
+
}
|
|
133
|
+
await batch.commit();
|
|
134
|
+
}
|
|
103
135
|
}
|
|
104
136
|
async function send(input) {
|
|
105
137
|
const { typeConfig } = getTypeConfig(input.type);
|
|
@@ -108,6 +140,6 @@ export function createNotificationHelper(db, config) {
|
|
|
108
140
|
}
|
|
109
141
|
return queueForBatch(input);
|
|
110
142
|
}
|
|
111
|
-
return { send, sendRealTime, queueForBatch };
|
|
143
|
+
return { send, sendRealTime, queueForBatch, queueManyForBatch };
|
|
112
144
|
}
|
|
113
145
|
//# sourceMappingURL=createNotificationHelper.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createNotificationHelper.js","sourceRoot":"","sources":["../../src/server/createNotificationHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAC/B,MAAM,iBAAiB,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"createNotificationHelper.js","sourceRoot":"","sources":["../../src/server/createNotificationHelper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed errors thrown by notification-core server helpers.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Thrown when a caller is not allowed to perform a notification action — e.g.
|
|
6
|
+
* archiving a personal notification they do not own, or a non-admin archiving a
|
|
7
|
+
* shared notification. Consuming callables should catch this and map it to a
|
|
8
|
+
* `permission-denied` error code rather than surfacing a generic `internal`.
|
|
9
|
+
*/
|
|
10
|
+
export declare class NotificationPermissionError extends Error {
|
|
11
|
+
constructor(message: string);
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/server/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;GAKG;AACH,qBAAa,2BAA4B,SAAQ,KAAK;gBACxC,OAAO,EAAE,MAAM;CAO5B"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed errors thrown by notification-core server helpers.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Thrown when a caller is not allowed to perform a notification action — e.g.
|
|
6
|
+
* archiving a personal notification they do not own, or a non-admin archiving a
|
|
7
|
+
* shared notification. Consuming callables should catch this and map it to a
|
|
8
|
+
* `permission-denied` error code rather than surfacing a generic `internal`.
|
|
9
|
+
*/
|
|
10
|
+
export class NotificationPermissionError extends Error {
|
|
11
|
+
constructor(message) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = 'NotificationPermissionError';
|
|
14
|
+
// Restore the prototype chain so `instanceof` works across the transpile
|
|
15
|
+
// target (extending built-ins can break it otherwise).
|
|
16
|
+
Object.setPrototypeOf(this, NotificationPermissionError.prototype);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/server/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;GAKG;AACH,MAAM,OAAO,2BAA4B,SAAQ,KAAK;IACpD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAC;QAC1C,yEAAyE;QACzE,uDAAuD;QACvD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,2BAA2B,CAAC,SAAS,CAAC,CAAC;IACrE,CAAC;CACF"}
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { createNotificationHelper } from './createNotificationHelper.js';
|
|
2
2
|
export { processBatchHelper } from './processBatchHelper.js';
|
|
3
3
|
export { archiveNotificationHelper, archiveAllNotificationsHelper, } from './archiveNotificationHelper.js';
|
|
4
|
+
export { markSeenHelper } from './markSeenHelper.js';
|
|
5
|
+
export { NotificationPermissionError } from './errors.js';
|
|
4
6
|
export type { ServerFirestore, ServerCollectionRef, ServerQuery, ServerQuerySnapshot, ServerDocSnapshot, ServerDocRef, ServerWriteBatch, CreateNotificationInput, NotificationHelper, } from './types.js';
|
|
5
7
|
//# 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;
|
|
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"}
|
package/dist/server/index.js
CHANGED
|
@@ -2,4 +2,6 @@
|
|
|
2
2
|
export { createNotificationHelper } from './createNotificationHelper.js';
|
|
3
3
|
export { processBatchHelper } from './processBatchHelper.js';
|
|
4
4
|
export { archiveNotificationHelper, archiveAllNotificationsHelper, } from './archiveNotificationHelper.js';
|
|
5
|
+
export { markSeenHelper } from './markSeenHelper.js';
|
|
6
|
+
export { NotificationPermissionError } from './errors.js';
|
|
5
7
|
//# sourceMappingURL=index.js.map
|
package/dist/server/index.js.map
CHANGED
|
@@ -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"}
|
|
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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mark-seen helper — used by the app's `markNotificationsSeen` callable.
|
|
3
|
+
* Batches `seenAt = now` writes for a set of active notification doc refs.
|
|
4
|
+
*/
|
|
5
|
+
import type { ServerFirestore, ServerDocRef } from './types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Stamp `seenAt` on a set of active notification doc refs, writing in
|
|
8
|
+
* ≤500-write chunks per commit (the Firestore batch limit).
|
|
9
|
+
*
|
|
10
|
+
* Generic — no domain knowledge. The consuming app's callable supplies the
|
|
11
|
+
* ownership-filtered set of refs (personal `targetUserId == uid`); this helper
|
|
12
|
+
* just stamps them. It does not archive and writes no audit event.
|
|
13
|
+
*/
|
|
14
|
+
export declare function markSeenHelper(db: ServerFirestore, docRefs: ServerDocRef[], seenAt: number): Promise<{
|
|
15
|
+
updated: number;
|
|
16
|
+
}>;
|
|
17
|
+
//# sourceMappingURL=markSeenHelper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markSeenHelper.d.ts","sourceRoot":"","sources":["../../src/server/markSeenHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAKhE;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,eAAe,EACnB,OAAO,EAAE,YAAY,EAAE,EACvB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAe9B"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mark-seen helper — used by the app's `markNotificationsSeen` callable.
|
|
3
|
+
* Batches `seenAt = now` writes for a set of active notification doc refs.
|
|
4
|
+
*/
|
|
5
|
+
/** Firestore hard limit on writes per batch. */
|
|
6
|
+
const MAX_BATCH_WRITES = 500;
|
|
7
|
+
/**
|
|
8
|
+
* Stamp `seenAt` on a set of active notification doc refs, writing in
|
|
9
|
+
* ≤500-write chunks per commit (the Firestore batch limit).
|
|
10
|
+
*
|
|
11
|
+
* Generic — no domain knowledge. The consuming app's callable supplies the
|
|
12
|
+
* ownership-filtered set of refs (personal `targetUserId == uid`); this helper
|
|
13
|
+
* just stamps them. It does not archive and writes no audit event.
|
|
14
|
+
*/
|
|
15
|
+
export async function markSeenHelper(db, docRefs, seenAt) {
|
|
16
|
+
if (docRefs.length === 0) {
|
|
17
|
+
return { updated: 0 };
|
|
18
|
+
}
|
|
19
|
+
for (let i = 0; i < docRefs.length; i += MAX_BATCH_WRITES) {
|
|
20
|
+
const chunk = docRefs.slice(i, i + MAX_BATCH_WRITES);
|
|
21
|
+
const batch = db.batch();
|
|
22
|
+
for (const ref of chunk) {
|
|
23
|
+
batch.update(ref, { seenAt });
|
|
24
|
+
}
|
|
25
|
+
await batch.commit();
|
|
26
|
+
}
|
|
27
|
+
return { updated: docRefs.length };
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=markSeenHelper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markSeenHelper.js","sourceRoot":"","sources":["../../src/server/markSeenHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,gDAAgD;AAChD,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAE7B;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,EAAmB,EACnB,OAAuB,EACvB,MAAc;IAEd,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IACxB,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,gBAAgB,EAAE,CAAC;QAC1D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,gBAAgB,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;YACxB,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAChC,CAAC;QACD,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC;IACvB,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;AACrC,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,
|
|
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,CA4K7B"}
|
|
@@ -47,8 +47,17 @@ export async function processBatchHelper(db, config) {
|
|
|
47
47
|
const typeConfig = config.types[data.type];
|
|
48
48
|
if (!typeConfig)
|
|
49
49
|
continue;
|
|
50
|
+
const categoryConfig = config.categories[data.category];
|
|
51
|
+
if (!categoryConfig)
|
|
52
|
+
continue;
|
|
50
53
|
const dedupKey = typeConfig.dedupKeyPattern(data.metadata);
|
|
51
|
-
|
|
54
|
+
// Personal notifications dedup per-recipient: a multi-recipient fan-out
|
|
55
|
+
// (same type/metadata, different targetUserId) must never collapse into
|
|
56
|
+
// one recipient's active doc. Shared notifications are intentionally a
|
|
57
|
+
// single doc for all admins (targetUserId is null).
|
|
58
|
+
const groupKey = categoryConfig.audienceType === 'personal'
|
|
59
|
+
? `${data.category}::${data.targetUserId}::${dedupKey}`
|
|
60
|
+
: `${data.category}::${dedupKey}`;
|
|
52
61
|
const existing = groups.get(groupKey);
|
|
53
62
|
if (existing) {
|
|
54
63
|
existing.count++;
|
|
@@ -82,12 +91,16 @@ export async function processBatchHelper(db, config) {
|
|
|
82
91
|
const dedupKey = typeConfig.dedupKeyPattern(group.metadata);
|
|
83
92
|
const countCap = typeConfig.countCap ?? DEFAULT_COUNT_CAP;
|
|
84
93
|
const actorCap = typeConfig.actorCap ?? DEFAULT_ACTOR_CAP;
|
|
85
|
-
// Check for existing active notification
|
|
86
|
-
|
|
94
|
+
// Check for existing active notification. Personal notifications are
|
|
95
|
+
// scoped to the recipient so different recipients never share an active
|
|
96
|
+
// doc; shared notifications omit targetUserId by design.
|
|
97
|
+
let existingQuery = db.collection(activePath)
|
|
87
98
|
.where('dedupKey', '==', dedupKey)
|
|
88
|
-
.where('category', '==', group.category)
|
|
89
|
-
|
|
90
|
-
|
|
99
|
+
.where('category', '==', group.category);
|
|
100
|
+
if (categoryConfig.audienceType === 'personal') {
|
|
101
|
+
existingQuery = existingQuery.where('targetUserId', '==', group.targetUserId);
|
|
102
|
+
}
|
|
103
|
+
const existingSnap = await existingQuery.limit(1).get();
|
|
91
104
|
if (!existingSnap.empty) {
|
|
92
105
|
// Increment existing
|
|
93
106
|
const existingDoc = existingSnap.docs[0];
|
|
@@ -105,6 +118,8 @@ export async function processBatchHelper(db, config) {
|
|
|
105
118
|
count: newCount,
|
|
106
119
|
latestActorIds: mergedActorIds,
|
|
107
120
|
message: typeConfig.messagePattern(group.metadata, newCount),
|
|
121
|
+
// New activity on an existing notification re-lights the unread badge.
|
|
122
|
+
seenAt: 0,
|
|
108
123
|
updatedAt: Date.now(),
|
|
109
124
|
});
|
|
110
125
|
notificationsUpdated++;
|
|
@@ -126,6 +141,8 @@ export async function processBatchHelper(db, config) {
|
|
|
126
141
|
latestActorIds: group.actorIds.slice(0, actorCap),
|
|
127
142
|
targetPath,
|
|
128
143
|
metadata: group.metadata,
|
|
144
|
+
// Active docs are created unseen so the unread count() predicate matches.
|
|
145
|
+
seenAt: 0,
|
|
129
146
|
createdAt: now,
|
|
130
147
|
updatedAt: now,
|
|
131
148
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"processBatchHelper.js","sourceRoot":"","sources":["../../src/server/processBatchHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAC/B,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAC5B,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAClC,MAAM,cAAc,GAAG,EAAE,CAAC;AAQ1B;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,EAAmB,EACnB,MAAgC;IAEhC,MAAM,WAAW,GAAG,MAAM,CAAC,qBAAqB,IAAI,sBAAsB,CAAC;IAC3E,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,CAAC,sCAAsC;IAE1E,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,IAAI,oBAAoB,GAAG,CAAC,CAAC;IAC7B,IAAI,oBAAoB,GAAG,CAAC,CAAC;IAC7B,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,OAAO,GAAG,IAAI,CAAC;IAEnB,OAAO,OAAO,IAAI,UAAU,GAAG,cAAc,EAAE,CAAC;QAC9C,UAAU,EAAE,CAAC;QAEb,MAAM,YAAY,GAAG,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC;aAC5C,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC;aAChC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC;aAC3B,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAEhC,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,CAAC;QAE1C,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnB,OAAO,GAAG,KAAK,CAAC;YAChB,MAAM;QACR,CAAC;QAED,oBAAoB;QACpB,MAAM,MAAM,GAAG,IAAI,GAAG,EAQlB,CAAC;QAEL,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;YACpC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAqC,CAAC;YAC/D,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3C,IAAI,CAAC,UAAU;gBAAE,SAAS;
|
|
1
|
+
{"version":3,"file":"processBatchHelper.js","sourceRoot":"","sources":["../../src/server/processBatchHelper.ts"],"names":[],"mappings":"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"}
|
package/dist/server/types.d.ts
CHANGED
|
@@ -75,5 +75,11 @@ export interface NotificationHelper {
|
|
|
75
75
|
sendRealTime(input: CreateNotificationInput): Promise<void>;
|
|
76
76
|
/** Queue for batch processing */
|
|
77
77
|
queueForBatch(input: CreateNotificationInput): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Queue many pending docs at once, writing in ≤500-write chunks per commit
|
|
80
|
+
* (the Firestore batch limit). Generic per-user fan-out primitive — it only
|
|
81
|
+
* sees uids + payload; the batch processor materializes per-user active docs.
|
|
82
|
+
*/
|
|
83
|
+
queueManyForBatch(inputs: CreateNotificationInput[]): Promise<void>;
|
|
78
84
|
}
|
|
79
85
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -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/dist/types.d.ts
CHANGED
|
@@ -35,6 +35,15 @@ export interface NotificationDoc {
|
|
|
35
35
|
targetPath: string;
|
|
36
36
|
/** Type-specific metadata (e.g. { entityId, reason }) */
|
|
37
37
|
metadata: Record<string, unknown>;
|
|
38
|
+
/**
|
|
39
|
+
* Epoch ms the recipient last marked this notification seen, or `0` when
|
|
40
|
+
* unseen. Generic field — no domain knowledge. Always present (initialized
|
|
41
|
+
* to `0` on creation and reset to `0` on dedup-increment) so the unread
|
|
42
|
+
* `count()` aggregation can match it with a `seenAt == 0` equality predicate.
|
|
43
|
+
* `seenAt` is a personal concept; shared notifications carry it for shape
|
|
44
|
+
* uniformity but their unread indicator is existence-based and ignores it.
|
|
45
|
+
*/
|
|
46
|
+
seenAt: number;
|
|
38
47
|
/** First occurrence */
|
|
39
48
|
createdAt: number;
|
|
40
49
|
/** Latest occurrence */
|
|
@@ -48,8 +57,6 @@ export interface ArchivalInfo {
|
|
|
48
57
|
archivedBy: string;
|
|
49
58
|
/** Epoch ms */
|
|
50
59
|
archivedAt: number;
|
|
51
|
-
/** Device context */
|
|
52
|
-
device: 'web' | 'mobile';
|
|
53
60
|
}
|
|
54
61
|
/**
|
|
55
62
|
* History document — extends active with archival info.
|
|
@@ -57,6 +64,13 @@ export interface ArchivalInfo {
|
|
|
57
64
|
export interface NotificationHistoryDoc extends NotificationDoc {
|
|
58
65
|
/** Who/when/how it was archived */
|
|
59
66
|
archival: ArchivalInfo;
|
|
67
|
+
/**
|
|
68
|
+
* Epoch ms after which native Firestore TTL may delete this history doc.
|
|
69
|
+
* The retention window is app policy (set by the consuming app at archive
|
|
70
|
+
* time); the helper just persists whatever value it is handed. Generic
|
|
71
|
+
* field — no domain knowledge.
|
|
72
|
+
*/
|
|
73
|
+
expireAt: number;
|
|
60
74
|
/** Admin userId (admin history only, quick-access field) */
|
|
61
75
|
handledBy?: string;
|
|
62
76
|
}
|
|
@@ -142,15 +156,26 @@ export interface UseUnreadCountOptions {
|
|
|
142
156
|
countLimit?: number;
|
|
143
157
|
}
|
|
144
158
|
export interface UseArchiveNotificationOptions {
|
|
145
|
-
config: NotificationSystemConfig;
|
|
146
159
|
userId: string;
|
|
147
160
|
category: string;
|
|
161
|
+
/**
|
|
162
|
+
* App-supplied adapter that performs the archive (active → history) for one
|
|
163
|
+
* notification — typically `httpsCallable(functions, 'archiveNotification')`.
|
|
164
|
+
* The hook performs no client Firestore writes; it only invalidates the read
|
|
165
|
+
* keys on success.
|
|
166
|
+
*/
|
|
167
|
+
archiveFn: (notificationId: string) => Promise<unknown>;
|
|
148
168
|
invalidateKeys?: readonly unknown[][];
|
|
149
169
|
}
|
|
150
170
|
export interface UseArchiveAllNotificationsOptions {
|
|
151
|
-
config: NotificationSystemConfig;
|
|
152
171
|
userId: string;
|
|
153
172
|
category: string;
|
|
173
|
+
/**
|
|
174
|
+
* App-supplied adapter that archives the caller's whole category — typically
|
|
175
|
+
* an `httpsCallable(functions, 'archiveNotification')` invoked with the
|
|
176
|
+
* `{ kind: 'all' }` scope. The hook performs no client Firestore writes.
|
|
177
|
+
*/
|
|
178
|
+
archiveAllFn: () => Promise<unknown>;
|
|
154
179
|
invalidateKeys?: readonly unknown[][];
|
|
155
180
|
}
|
|
156
181
|
export interface UseNotificationHistoryOptions {
|
|
@@ -165,9 +190,18 @@ export interface NotificationListProps {
|
|
|
165
190
|
userId: string;
|
|
166
191
|
category: string;
|
|
167
192
|
onNotificationClick: (notification: NotificationDoc) => void;
|
|
193
|
+
/**
|
|
194
|
+
* Adapter that archives one notification (active → history). Passed straight
|
|
195
|
+
* through to `useArchiveNotification`; the app wires it to its callable.
|
|
196
|
+
*/
|
|
197
|
+
archiveFn: (notificationId: string) => Promise<unknown>;
|
|
198
|
+
/**
|
|
199
|
+
* Adapter that archives the caller's whole category. Passed straight through
|
|
200
|
+
* to `useArchiveAllNotifications`; the app wires it to its callable.
|
|
201
|
+
*/
|
|
202
|
+
archiveAllFn: () => Promise<unknown>;
|
|
168
203
|
onClearAll?: () => void;
|
|
169
204
|
refetchInterval?: number;
|
|
170
|
-
device?: 'web' | 'mobile';
|
|
171
205
|
emptyText?: string;
|
|
172
206
|
}
|
|
173
207
|
export interface NotificationEmptyStateProps {
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,uBAAuB;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IAGjB,4DAA4D;IAC5D,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAG5B,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,wBAAwB;IACxB,OAAO,EAAE,MAAM,CAAC;IAGhB,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,cAAc,EAAE,MAAM,EAAE,CAAC;IAGzB,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAGlC,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,mCAAmC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe;IACf,UAAU,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/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.
|
|
3
|
+
"version": "0.4.4",
|
|
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",
|