@ttt-productions/notification-core 0.15.16 → 0.15.17

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.
Files changed (58) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/react/components/NotificationHistoryList.d.ts +1 -1
  5. package/dist/react/components/NotificationHistoryList.d.ts.map +1 -1
  6. package/dist/react/components/NotificationHistoryList.js +4 -1
  7. package/dist/react/components/NotificationHistoryList.js.map +1 -1
  8. package/dist/react/components/NotificationList.d.ts +1 -1
  9. package/dist/react/components/NotificationList.d.ts.map +1 -1
  10. package/dist/react/components/NotificationList.js +24 -9
  11. package/dist/react/components/NotificationList.js.map +1 -1
  12. package/dist/react/components/NotificationUnreadBadge.d.ts.map +1 -1
  13. package/dist/react/components/NotificationUnreadBadge.js +1 -1
  14. package/dist/react/components/NotificationUnreadBadge.js.map +1 -1
  15. package/dist/react/hooks/useActiveNotifications.d.ts +3 -3
  16. package/dist/react/hooks/useActiveNotifications.d.ts.map +1 -1
  17. package/dist/react/hooks/useActiveNotifications.js +1 -2
  18. package/dist/react/hooks/useActiveNotifications.js.map +1 -1
  19. package/dist/react/hooks/useArchiveAllNotifications.d.ts.map +1 -1
  20. package/dist/react/hooks/useArchiveAllNotifications.js +14 -2
  21. package/dist/react/hooks/useArchiveAllNotifications.js.map +1 -1
  22. package/dist/react/hooks/useNotificationHistory.d.ts +3 -3
  23. package/dist/react/hooks/useNotificationHistory.d.ts.map +1 -1
  24. package/dist/react/hooks/useNotificationHistory.js +1 -2
  25. package/dist/react/hooks/useNotificationHistory.js.map +1 -1
  26. package/dist/react/hooks/useUnreadCount.d.ts.map +1 -1
  27. package/dist/react/hooks/useUnreadCount.js +1 -3
  28. package/dist/react/hooks/useUnreadCount.js.map +1 -1
  29. package/dist/react/index.d.ts +10 -2
  30. package/dist/react/index.d.ts.map +1 -1
  31. package/dist/react/index.js +10 -3
  32. package/dist/react/index.js.map +1 -1
  33. package/dist/react/types.d.ts +72 -0
  34. package/dist/react/types.d.ts.map +1 -0
  35. package/dist/react/types.js +2 -0
  36. package/dist/react/types.js.map +1 -0
  37. package/dist/server/delivery-ledger.d.ts.map +1 -1
  38. package/dist/server/delivery-ledger.js +6 -4
  39. package/dist/server/delivery-ledger.js.map +1 -1
  40. package/dist/server/observed-generation.d.ts.map +1 -1
  41. package/dist/server/observed-generation.js.map +1 -1
  42. package/dist/server/processBatchHelper.d.ts.map +1 -1
  43. package/dist/server/processBatchHelper.js +3 -5
  44. package/dist/server/processBatchHelper.js.map +1 -1
  45. package/dist/server/types.d.ts.map +1 -1
  46. package/dist/server/types.js.map +1 -1
  47. package/dist/types.d.ts +0 -70
  48. package/dist/types.d.ts.map +1 -1
  49. package/dist/types.js.map +1 -1
  50. package/package.json +5 -5
  51. package/dist/react/components/index.d.ts +0 -5
  52. package/dist/react/components/index.d.ts.map +0 -1
  53. package/dist/react/components/index.js +0 -5
  54. package/dist/react/components/index.js.map +0 -1
  55. package/dist/react/hooks/index.d.ts +0 -6
  56. package/dist/react/hooks/index.d.ts.map +0 -1
  57. package/dist/react/hooks/index.js +0 -6
  58. package/dist/react/hooks/index.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
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;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAGlC;;;;;;;OAOG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAG1B,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAQD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,sBAAsB;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,eAAe;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,WAAW,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,8EAA8E;IAC9E,YAAY,EAAE,UAAU,GAAG,QAAQ,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB;IACpB,QAAQ,EAAE,UAAU,GAAG,QAAQ,CAAC;IAChC,mDAAmD;IACnD,eAAe,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC;IAC/D,gDAAgD;IAChD,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC;IAC5D,0DAA0D;IAC1D,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7E;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC,CAAC;IAC7E,qCAAqC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC;IACvD,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAC9C,uDAAuD;IACvD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,sFAAsF;IACtF,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,uFAAuF;IACvF,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAMD,MAAM,WAAW,6BAA6B;IAC5C,MAAM,EAAE,wBAAwB,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yFAAyF;IACzF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,uBAAwB,SAAQ,eAAe;IAC9D,mEAAmE;IACnE,mBAAmB,EAAE,MAAM,CAAC;IAC5B,2EAA2E;IAC3E,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,6BAA6B;IAC5C,MAAM,EAAE,wBAAwB,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,wBAAwB,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAClC,YAAY,EAAE,eAAe,KAC1B,OAAO,CAAC,yBAAyB,CAAC,CAAC;AAExC,MAAM,WAAW,6BAA6B;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,SAAS,EAAE,qBAAqB,CAAC;IACjC,cAAc,CAAC,EAAE,SAAS,OAAO,EAAE,EAAE,CAAC;CACvC;AAaD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,mBAAmB,GAC7B,MAAM,GAAG,WAAW,GAAG,aAAa,GAAG,UAAU,GAAG,YAAY,GAAG,QAAQ,CAAC;AAE9E;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,yDAAyD;IACzD,KAAK,EAAE,aAAa,GAAG,UAAU,GAAG,YAAY,GAAG,QAAQ,CAAC;IAC5D,6FAA6F;IAC7F,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,OAAO,CAAC,mBAAmB,EAAE,UAAU,GAAG,YAAY,GAAG,QAAQ,CAAC,CAAC;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iCAAiC;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,mBAAmB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC5E;;;;;OAKG;IACH,qBAAqB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACzE,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,SAAS,OAAO,EAAE,EAAE,CAAC;CACvC;AAMD;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACrC,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,2BAA2B;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,4BAA4B;IAC3C,MAAM,EAAE,wBAAwB,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG","sourcesContent":["/**\n * @ttt-productions/notification-core — Type definitions\n *\n * Two-tier notification system: active (unread) → history (archived).\n * No `isRead` flag — existence in the active collection means unread.\n */\n\n// Type-only import: erased at compile time, so this does not force React into\n// the server-safe main entry's runtime graph (the `react` peer dep stays optional).\nimport type { ReactNode } from 'react';\n\n// ============================================================================\n// DOCUMENT TYPES\n// ============================================================================\n\n/**\n * Active notification document stored in Firestore.\n * Same shape for both user and admin collections.\n */\nexport interface NotificationDoc {\n /** Firestore doc ID */\n id: string;\n /** Notification type (e.g. 'content_report', 'entity_invite') */\n type: string;\n /** Dedup key (e.g. 'report_entityXYZ') — same key = same notification */\n dedupKey: string;\n /** Category: 'user' | 'admin' (extensible) */\n category: string;\n\n // Targeting\n /** userId for 'user' category, null for 'admin' (shared) */\n targetUserId: string | null;\n\n // Display\n /** Notification title */\n title: string;\n /** Notification body */\n message: string;\n\n // Dedup aggregation\n /** Incremented on duplicates */\n count: number;\n /**\n * Last N actor user IDs (capped). Identity is stored id-only — display names\n * are resolved at read time by the consuming app (e.g. from publicUsers), so\n * they never drift in the persisted doc.\n */\n latestActorIds: string[];\n\n // Navigation\n /**\n * Route path when clicked (e.g. '/admin' or '/entities/abc'). ABSENT when the\n * type declares no `defaultTargetPath` — a linkless, informational-only\n * notification (the consumer renders no \"go to\" affordance for it).\n */\n targetPath?: string;\n /** Type-specific metadata (e.g. { entityId, reason }) */\n metadata: Record<string, unknown>;\n\n // Seen state (personal notifications)\n /**\n * Epoch ms the recipient last marked this notification seen, or `0` when\n * unseen. Generic field — no domain knowledge. Always present (initialized\n * to `0` on creation and reset to `0` on dedup-increment) so the unread\n * `count()` aggregation can match it with a `seenAt == 0` equality predicate.\n * `seenAt` is a personal concept; shared notifications carry it for shape\n * uniformity but their unread indicator is existence-based and ignores it.\n */\n seenAt: number;\n\n /**\n * Opaque per-generation token (uuid), minted FRESH whenever the active doc is\n * created or materially re-lit. The SEEN/ARCHIVE precondition compares against\n * THIS, not a restartable integer: the active doc id is deterministic, so a\n * delete+recreate would restart an integer and let a stale tab's \"version 1\"\n * match a different card it never saw (ABA). An opaque token cannot repeat.\n * Optional on the legacy active doc shape; the ledger materializer always sets it.\n */\n activityGeneration?: string;\n /** The `activityGeneration` observed at the time `seenAt` was last set. */\n seenAtGeneration?: string;\n\n // Timestamps (epoch ms)\n /** First occurrence */\n createdAt: number;\n /** Latest occurrence */\n updatedAt: number;\n}\n\n// Archived history docs are persisted as an untyped wrapper by the server archive\n// helper (server/observed-generation.ts) — `archivedSnapshot` (the full active doc)\n// plus archive metadata + a native-TTL `expireAt` Timestamp. There is no consumer-\n// facing TS type for that shape; the canonical registry schema lives in the\n// consuming app's core package (doc-schemas/notifications.ts → NotificationHistoryDocSchema).\n\n/**\n * Pending notification — queue item for the batch processor.\n */\nexport interface PendingNotification {\n id: string;\n /** Notification type */\n type: string;\n /** Target category */\n category: string;\n /** Target userId (null for admin/shared) */\n targetUserId: string | null;\n /** Who triggered this (id-only; display name resolved at read time) */\n actorId: string;\n /** Type-specific data for building the notification */\n metadata: Record<string, unknown>;\n /** Epoch ms */\n createdAt: number;\n}\n\n// ============================================================================\n// CONFIGURATION TYPES\n// ============================================================================\n\n/**\n * Per-category configuration (user vs admin).\n */\nexport interface NotificationCategoryConfig {\n /** Firestore collection path for active notifications */\n activePath: string;\n /** Function that returns the history collection path */\n historyPath: (userId?: string) => string;\n /** 'personal' requires targetUserId, 'shared' = all members see everything */\n audienceType: 'personal' | 'shared';\n}\n\n/**\n * Per-type configuration for a notification type.\n */\nexport interface NotificationTypeConfig {\n /** Which category this type belongs to */\n category: string;\n /** Delivery mode */\n delivery: 'realtime' | 'queued';\n /** Function to build the dedupKey from metadata */\n dedupKeyPattern: (metadata: Record<string, unknown>) => string;\n /** Function to build the title from metadata */\n titlePattern: (metadata: Record<string, unknown>) => string;\n /** Function to build the message from metadata + count */\n messagePattern: (metadata: Record<string, unknown>, count: number) => string;\n /**\n * Default target path, or function to build from metadata. OMIT to declare a\n * linkless type: the written doc carries no `targetPath` and the consumer\n * renders no \"go to\" affordance (clear-only rows).\n */\n defaultTargetPath?: string | ((metadata: Record<string, unknown>) => string);\n /** Max count value (default 5000) */\n countCap?: number;\n /** Max latestActorIds array length (default 5) */\n actorCap?: number;\n /** Icon/emoji for display (optional) */\n icon?: string;\n}\n\n/**\n * Full notification system configuration — provided by each app.\n */\nexport interface NotificationSystemConfig {\n /** Category definitions */\n categories: Record<string, NotificationCategoryConfig>;\n /** Type definitions */\n types: Record<string, NotificationTypeConfig>;\n /** Batch processor interval in minutes (default 10) */\n batchIntervalMinutes?: number;\n /** Firestore collection for pending notifications (default 'pendingNotifications') */\n pendingCollectionPath?: string;\n /** Firestore collection for the delivery ledger (default 'notificationDeliveries'). */\n deliveriesCollectionPath?: string;\n /**\n * Factory that converts epoch-ms to the app's Firestore `Timestamp` instance.\n * REQUIRED for the delivery ledger: Firestore native TTL acts ONLY on\n * `Timestamp` fields, so `expireAt` must be a real Timestamp (never a number).\n * The generic package never imports firebase-admin, so the app injects this\n * (e.g. `(ms) => admin.firestore.Timestamp.fromMillis(ms)`).\n */\n timestampFromMillis?: (ms: number) => unknown;\n /** Delivery-row TTL after materialization, in ms (default 90 days). */\n deliveryTtlMs?: number;\n /** Max delivery attempts before a row dead-letters (default 8). */\n maxDeliveryAttempts?: number;\n}\n\n// ============================================================================\n// HOOK OPTION TYPES\n// ============================================================================\n\nexport interface UseActiveNotificationsOptions {\n config: NotificationSystemConfig;\n userId: string;\n category: string;\n enabled?: boolean;\n pageSize?: number;\n /** Re-read the displayed page every `refetchInterval` ms while mounted (default 30s). */\n refetchInterval?: number;\n /** How long a read page counts as fresh, in ms (default 30s). */\n staleTime?: number;\n}\n\n/**\n * A flattened archived-history item for the read surface. The history doc is a\n * wrapper (`archivedSnapshot` + archive metadata + TTL); this shape lifts the\n * snapshot's display fields to the top level so the history list renders exactly\n * like the active list, plus `archivedAt` for ordering/display and\n * `archiveOccurrenceId` as the stable React key.\n */\nexport interface NotificationHistoryItem extends NotificationDoc {\n /** The history doc id (stable key — the `archiveOccurrenceId`). */\n archiveOccurrenceId: string;\n /** Epoch ms the notification was archived (history docs order by this). */\n archivedAt: number;\n}\n\nexport interface UseNotificationHistoryOptions {\n config: NotificationSystemConfig;\n userId: string;\n category: string;\n enabled?: boolean;\n pageSize?: number;\n /** Read-freshness stale time in ms (archived rows are immutable; default 60s). */\n staleTime?: number;\n}\n\nexport interface UseUnreadCountOptions {\n config: NotificationSystemConfig;\n userId: string;\n category: string;\n enabled?: boolean;\n refetchInterval?: number;\n countLimit?: number;\n}\n\n/**\n * What an archive adapter answers: whether the card was archived. `false` means the\n * server archived nothing (for example the card gained new activity after it was\n * rendered); the row stays active and is not shown as clearing.\n */\nexport interface NotificationArchiveResult {\n archived: boolean;\n}\n\n/**\n * App-supplied adapter that archives one rendered notification (active → history).\n * It receives the row exactly as the list rendered it, so the app can send what it\n * observed (e.g. the row's activity generation). It rejects on failure and resolves\n * whether the card was archived.\n */\nexport type NotificationArchiveFn = (notification: NotificationDoc) => Promise<NotificationArchiveResult>;\n\nexport interface UseArchiveNotificationOptions {\n userId: string;\n category: string;\n /**\n * Performs the archive through the app's callable. The hook performs no client\n * Firestore writes; it only invalidates the read keys on success.\n */\n archiveFn: NotificationArchiveFn;\n invalidateKeys?: readonly unknown[][];\n}\n\n// ----------------------------------------------------------------------------\n// Archive-all — server-owned job + thin client status poller\n// ----------------------------------------------------------------------------\n//\n// Archive-all is NOT a browser loop. The client enqueues ONE server-owned\n// archive-all job (scoped to a single notification category/tab), then polls its\n// status until the job reaches a terminal state. All paging + ownership-checked\n// per-card deletion happen server-side in a bounded scheduled/queued worker; the\n// hook never touches Firestore and never chains archive calls. The generic\n// package hardcodes NO callable name — the app injects both adapters below.\n\n/**\n * Terminal + transient states of a server-owned archive-all job, as surfaced to the UI.\n *\n * - `idle` — nothing enqueued yet (initial / reset state).\n * - `enqueuing` — the enqueue adapter is in flight (job not yet acknowledged).\n * - `in-progress` — the job is enqueued/running; the worker is still draining the category.\n * - `complete` — TERMINAL: the worker fully drained the category's active set.\n * - `incomplete` — TERMINAL: the job stopped without draining everything (e.g. hit its own\n * bound / a non-advanceable card). The tray keeps a \"some remain — try again\"\n * affordance, mirroring the old loop's incomplete result.\n * - `failed` — TERMINAL: the enqueue call threw, or the job dead-lettered / reported failure.\n */\nexport type ArchiveAllJobStatus =\n | 'idle'\n | 'enqueuing'\n | 'in-progress'\n | 'complete'\n | 'incomplete'\n | 'failed';\n\n/**\n * Result of the INJECTED enqueue adapter — triggers exactly one server-owned archive-all job for\n * the given category and returns immediately with the job's id (idempotent per user+category+request\n * on the app side). The app wires this to its `httpsCallable(functions, 'enqueueArchiveAll')`\n * (or equivalent); the generic package never names the callable.\n */\nexport interface EnqueueArchiveAllResult {\n /** Server job id the poller then polls via the status adapter. */\n jobId: string;\n}\n\n/**\n * Snapshot of a server-owned archive-all job, returned by the INJECTED status-query adapter.\n * The poller maps `state` → {@link ArchiveAllJobStatus} and stops polling on any terminal state.\n * `category` echoes the tab/category the job was enqueued for so the UI can assert per-tab scoping.\n */\nexport interface ArchiveAllJobSnapshot {\n /** Job lifecycle state as owned by the server worker. */\n state: 'in-progress' | 'complete' | 'incomplete' | 'failed';\n /** The notification category/tab this job is scoped to (must match the enqueue category). */\n category: string;\n /** Cards archived so far (monotonic); optional progress for the UI. */\n archived?: number;\n /**\n * On a `complete` job: cards the drain could not archive, which are still in the list. A job\n * completes once it has walked the whole category, so a card that keeps failing on its own does\n * not hold the rest of the category back.\n */\n notArchived?: number;\n /** Human-readable failure reason when `state === 'failed'` (optional). */\n error?: string;\n}\n\n/**\n * Aggregate result the poller resolves with once the job reaches a terminal state.\n * `complete` is the load-bearing completion contract (true ONLY when the whole category was\n * drained), preserved from the old loop so callers gate side effects the same way.\n */\nexport interface ArchiveAllPollResult {\n status: Extract<ArchiveAllJobStatus, 'complete' | 'incomplete' | 'failed'>;\n category: string;\n archived: number;\n /** Cards a complete drain left in the list (each failed on its own); 0 otherwise. */\n notArchived: number;\n complete: boolean;\n error?: string;\n}\n\nexport interface UseArchiveAllNotificationsOptions {\n userId: string;\n category: string;\n /**\n * App-supplied adapter that ENQUEUES one server-owned archive-all job scoped to `category` and\n * returns its `jobId`. The `category` is passed so the app callable can carry the tab/source into\n * the job (per-tab scoping is REQUIRED — the worker archives only that category's active cards).\n * Typically `(category) => enqueueArchiveAll({ category })` over an `httpsCallable`.\n */\n enqueueArchiveAllFn: (category: string) => Promise<EnqueueArchiveAllResult>;\n /**\n * App-supplied adapter that returns the current {@link ArchiveAllJobSnapshot} for a job id — the\n * hook polls it until the job reaches a terminal state. Typically\n * `(jobId) => getArchiveAllStatus({ jobId })` over an `httpsCallable`, or a Firestore read of the\n * job doc. No client Firestore writes.\n */\n getArchiveAllStatusFn: (jobId: string) => Promise<ArchiveAllJobSnapshot>;\n /** Poll interval in ms while the job is in-progress (default 1500). */\n pollIntervalMs?: number;\n /**\n * Max number of status polls before the poller gives up and resolves `incomplete` (guards a job\n * that never reaches a terminal state — default 120, i.e. ~3 min at the default interval).\n */\n maxPolls?: number;\n invalidateKeys?: readonly unknown[][];\n}\n\n// ============================================================================\n// COMPONENT PROP TYPES\n// ============================================================================\n\n/**\n * Per-row actions the list hands to `renderRowAction`. The row itself is inert\n * — every affordance lives in the controls the consumer\n * renders in the slot. `archive` performs the active→history archive for that\n * row; it is present ONLY on the active list (archived history rows cannot be\n * re-archived, so it is absent there).\n */\nexport interface NotificationRowActions {\n /** Archives this row; rejects when the archive fails. */\n archive?: () => Promise<void>;\n /**\n * True while this row is archiving, including a category-wide Clear All. After an\n * archive the server confirmed, it stays true until the row leaves the active list.\n */\n isArchivePending?: boolean;\n}\n\n/**\n * What a list hands its `renderError` slot when its read failed. `hasRows` is true when\n * rows from an earlier read are still on screen above the slot (a failed refresh);\n * `retry` re-reads the displayed page and `retrying` is that read's pending flag.\n */\nexport interface NotificationListErrorState {\n error: Error;\n retry: () => void;\n retrying: boolean;\n hasRows: boolean;\n}\n\nexport interface NotificationListProps {\n config: NotificationSystemConfig;\n userId: string;\n category: string;\n /**\n * Archives one rendered notification. Passed straight through to\n * `useArchiveNotification`; the app wires it to its callable.\n */\n archiveFn: NotificationArchiveFn;\n /**\n * Adapter that ENQUEUES one server-owned archive-all job scoped to `category` and returns its\n * `jobId`. Passed straight through to `useArchiveAllNotifications`; the app wires it to its\n * enqueue callable. Per-tab scoping: the category flows through to the job.\n */\n enqueueArchiveAllFn: (category: string) => Promise<EnqueueArchiveAllResult>;\n /**\n * Adapter that returns the current status snapshot for an archive-all `jobId`. Passed straight\n * through to `useArchiveAllNotifications`, which polls it until the job is terminal; the app wires\n * it to its status callable / job-doc read.\n */\n getArchiveAllStatusFn: (jobId: string) => Promise<ArchiveAllJobSnapshot>;\n /** Left-aligned title for the active-list header. */\n title?: ReactNode;\n /**\n * Fires with the terminal result ONLY when the archive-all job completed — the whole category was\n * walked. A complete result can still carry `notArchived > 0` (cards that each failed and stay in\n * the list); the copy for that is the app's.\n */\n onClearAll?: (result: ArchiveAllPollResult) => void;\n /** Re-read the displayed page every `refetchInterval` ms while mounted (default 30s). */\n refetchInterval?: number;\n /** How long a read page counts as fresh, in ms (default 30s). */\n staleTime?: number;\n /** Empty-state text, shown only for an answered, empty first page. */\n emptyText?: string;\n /** The failed-read state, shown before (never instead of) the pager. Copy is the app's. */\n renderError: (state: NotificationListErrorState) => ReactNode;\n /**\n * Called with the rows on screen each time the displayed page's answered rows change\n * (not while a page is loading or failed with nothing shown) — the rows to mark seen.\n */\n onRenderedRowsChange?: (rows: readonly NotificationDoc[]) => void;\n /**\n * Per-row control slot. The row itself is inert; the consumer renders the row's\n * controls here — typically an ArrowRight \"go to\" (which may call `actions.archive`\n * then navigate) plus a clear/archive button (calls `actions.archive`). Omit to render\n * a row with no controls.\n */\n renderRowAction?: (notification: NotificationDoc, actions: NotificationRowActions) => ReactNode;\n}\n\nexport interface NotificationHistoryListProps {\n config: NotificationSystemConfig;\n userId: string;\n category: string;\n pageSize?: number;\n staleTime?: number;\n /** Empty-state text, shown only for an answered, empty first page. */\n emptyText?: string;\n /** The failed-read state, shown before (never instead of) the pager. Copy is the app's. */\n renderError: (state: NotificationListErrorState) => ReactNode;\n /** Left-aligned title for the read-only archived-list header. */\n title?: ReactNode;\n /**\n * Per-row control slot for archived rows. The row is inert; archived rows are\n * read-only (no re-archive), so `actions.archive` is absent — the consumer\n * typically renders only an ArrowRight \"go to\". Omit for a row with no controls.\n */\n renderRowAction?: (notification: NotificationHistoryItem, actions: NotificationRowActions) => ReactNode;\n}\n\nexport interface NotificationEmptyStateProps {\n text?: string;\n}\n\nexport interface NotificationUnreadBadgeProps {\n config: NotificationSystemConfig;\n userId: string;\n category: string;\n refetchInterval?: number;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG","sourcesContent":["/**\n * @ttt-productions/notification-core — Type definitions\n *\n * Two-tier notification system: active (unread) → history (archived).\n * No `isRead` flag — existence in the active collection means unread.\n */\n\n// ============================================================================\n// DOCUMENT TYPES\n// ============================================================================\n\n/**\n * Active notification document stored in Firestore.\n * Same shape for both user and admin collections.\n */\nexport interface NotificationDoc {\n /** Firestore doc ID */\n id: string;\n /** Notification type (e.g. 'content_report', 'entity_invite') */\n type: string;\n /** Dedup key (e.g. 'report_entityXYZ') — same key = same notification */\n dedupKey: string;\n /** Category: 'user' | 'admin' (extensible) */\n category: string;\n\n // Targeting\n /** userId for 'user' category, null for 'admin' (shared) */\n targetUserId: string | null;\n\n // Display\n /** Notification title */\n title: string;\n /** Notification body */\n message: string;\n\n // Dedup aggregation\n /** Incremented on duplicates */\n count: number;\n /**\n * Last N actor user IDs (capped). Identity is stored id-only — display names\n * are resolved at read time by the consuming app (e.g. from publicUsers), so\n * they never drift in the persisted doc.\n */\n latestActorIds: string[];\n\n // Navigation\n /**\n * Route path when clicked (e.g. '/admin' or '/entities/abc'). ABSENT when the\n * type declares no `defaultTargetPath` — a linkless, informational-only\n * notification (the consumer renders no \"go to\" affordance for it).\n */\n targetPath?: string;\n /** Type-specific metadata (e.g. { entityId, reason }) */\n metadata: Record<string, unknown>;\n\n // Seen state (personal notifications)\n /**\n * Epoch ms the recipient last marked this notification seen, or `0` when\n * unseen. Generic field — no domain knowledge. Always present (initialized\n * to `0` on creation and reset to `0` on dedup-increment) so the unread\n * `count()` aggregation can match it with a `seenAt == 0` equality predicate.\n * `seenAt` is a personal concept; shared notifications carry it for shape\n * uniformity but their unread indicator is existence-based and ignores it.\n */\n seenAt: number;\n\n /**\n * Opaque per-generation token (uuid), minted FRESH whenever the active doc is\n * created or materially re-lit. The SEEN/ARCHIVE precondition compares against\n * THIS, not a restartable integer: the active doc id is deterministic, so a\n * delete+recreate would restart an integer and let a stale tab's \"version 1\"\n * match a different card it never saw (ABA). An opaque token cannot repeat.\n * Optional on the legacy active doc shape; the ledger materializer always sets it.\n */\n activityGeneration?: string;\n /** The `activityGeneration` observed at the time `seenAt` was last set. */\n seenAtGeneration?: string;\n\n // Timestamps (epoch ms)\n /** First occurrence */\n createdAt: number;\n /** Latest occurrence */\n updatedAt: number;\n}\n\n// Archived history docs are persisted as an untyped wrapper by the server archive\n// helper (server/observed-generation.ts) — `archivedSnapshot` (the full active doc)\n// plus archive metadata + a native-TTL `expireAt` Timestamp. There is no consumer-\n// facing TS type for that shape; the canonical registry schema lives in the\n// consuming app's core package (doc-schemas/notifications.ts → NotificationHistoryDocSchema).\n\n/**\n * Pending notification — queue item for the batch processor.\n */\nexport interface PendingNotification {\n id: string;\n /** Notification type */\n type: string;\n /** Target category */\n category: string;\n /** Target userId (null for admin/shared) */\n targetUserId: string | null;\n /** Who triggered this (id-only; display name resolved at read time) */\n actorId: string;\n /** Type-specific data for building the notification */\n metadata: Record<string, unknown>;\n /** Epoch ms */\n createdAt: number;\n}\n\n// ============================================================================\n// CONFIGURATION TYPES\n// ============================================================================\n\n/**\n * Per-category configuration (user vs admin).\n */\nexport interface NotificationCategoryConfig {\n /** Firestore collection path for active notifications */\n activePath: string;\n /** Function that returns the history collection path */\n historyPath: (userId?: string) => string;\n /** 'personal' requires targetUserId, 'shared' = all members see everything */\n audienceType: 'personal' | 'shared';\n}\n\n/**\n * Per-type configuration for a notification type.\n */\nexport interface NotificationTypeConfig {\n /** Which category this type belongs to */\n category: string;\n /** Delivery mode */\n delivery: 'realtime' | 'queued';\n /** Function to build the dedupKey from metadata */\n dedupKeyPattern: (metadata: Record<string, unknown>) => string;\n /** Function to build the title from metadata */\n titlePattern: (metadata: Record<string, unknown>) => string;\n /** Function to build the message from metadata + count */\n messagePattern: (metadata: Record<string, unknown>, count: number) => string;\n /**\n * Default target path, or function to build from metadata. OMIT to declare a\n * linkless type: the written doc carries no `targetPath` and the consumer\n * renders no \"go to\" affordance (clear-only rows).\n */\n defaultTargetPath?: string | ((metadata: Record<string, unknown>) => string);\n /** Max count value (default 5000) */\n countCap?: number;\n /** Max latestActorIds array length (default 5) */\n actorCap?: number;\n /** Icon/emoji for display (optional) */\n icon?: string;\n}\n\n/**\n * Full notification system configuration — provided by each app.\n */\nexport interface NotificationSystemConfig {\n /** Category definitions */\n categories: Record<string, NotificationCategoryConfig>;\n /** Type definitions */\n types: Record<string, NotificationTypeConfig>;\n /** Batch processor interval in minutes (default 10) */\n batchIntervalMinutes?: number;\n /** Firestore collection for pending notifications (default 'pendingNotifications') */\n pendingCollectionPath?: string;\n /** Firestore collection for the delivery ledger (default 'notificationDeliveries'). */\n deliveriesCollectionPath?: string;\n /**\n * Factory that converts epoch-ms to the app's Firestore `Timestamp` instance.\n * REQUIRED for the delivery ledger: Firestore native TTL acts ONLY on\n * `Timestamp` fields, so `expireAt` must be a real Timestamp (never a number).\n * The generic package never imports firebase-admin, so the app injects this\n * (e.g. `(ms) => admin.firestore.Timestamp.fromMillis(ms)`).\n */\n timestampFromMillis?: (ms: number) => unknown;\n /** Delivery-row TTL after materialization, in ms (default 90 days). */\n deliveryTtlMs?: number;\n /** Max delivery attempts before a row dead-letters (default 8). */\n maxDeliveryAttempts?: number;\n}\n\n// ============================================================================\n// HOOK OPTION TYPES\n// ============================================================================\n\nexport interface UseActiveNotificationsOptions {\n config: NotificationSystemConfig;\n userId: string;\n category: string;\n enabled?: boolean;\n pageSize?: number;\n /** Re-read the displayed page every `refetchInterval` ms while mounted (default 30s). */\n refetchInterval?: number;\n /** How long a read page counts as fresh, in ms (default 30s). */\n staleTime?: number;\n}\n\n/**\n * A flattened archived-history item for the read surface. The history doc is a\n * wrapper (`archivedSnapshot` + archive metadata + TTL); this shape lifts the\n * snapshot's display fields to the top level so the history list renders exactly\n * like the active list, plus `archivedAt` for ordering/display and\n * `archiveOccurrenceId` as the stable React key.\n */\nexport interface NotificationHistoryItem extends NotificationDoc {\n /** The history doc id (stable key — the `archiveOccurrenceId`). */\n archiveOccurrenceId: string;\n /** Epoch ms the notification was archived (history docs order by this). */\n archivedAt: number;\n}\n\nexport interface UseNotificationHistoryOptions {\n config: NotificationSystemConfig;\n userId: string;\n category: string;\n enabled?: boolean;\n pageSize?: number;\n /** Read-freshness stale time in ms (archived rows are immutable; default 60s). */\n staleTime?: number;\n}\n\nexport interface UseUnreadCountOptions {\n config: NotificationSystemConfig;\n userId: string;\n category: string;\n enabled?: boolean;\n refetchInterval?: number;\n countLimit?: number;\n}\n\n/**\n * What an archive adapter answers: whether the card was archived. `false` means the\n * server archived nothing (for example the card gained new activity after it was\n * rendered); the row stays active and is not shown as clearing.\n */\nexport interface NotificationArchiveResult {\n archived: boolean;\n}\n\n/**\n * App-supplied adapter that archives one rendered notification (active → history).\n * It receives the row exactly as the list rendered it, so the app can send what it\n * observed (e.g. the row's activity generation). It rejects on failure and resolves\n * whether the card was archived.\n */\nexport type NotificationArchiveFn = (\n notification: NotificationDoc,\n) => Promise<NotificationArchiveResult>;\n\nexport interface UseArchiveNotificationOptions {\n userId: string;\n category: string;\n /**\n * Performs the archive through the app's callable. The hook performs no client\n * Firestore writes; it only invalidates the read keys on success.\n */\n archiveFn: NotificationArchiveFn;\n invalidateKeys?: readonly unknown[][];\n}\n\n// ----------------------------------------------------------------------------\n// Archive-all — server-owned job + thin client status poller\n// ----------------------------------------------------------------------------\n//\n// Archive-all is NOT a browser loop. The client enqueues ONE server-owned\n// archive-all job (scoped to a single notification category/tab), then polls its\n// status until the job reaches a terminal state. All paging + ownership-checked\n// per-card deletion happen server-side in a bounded scheduled/queued worker; the\n// hook never touches Firestore and never chains archive calls. The generic\n// package hardcodes NO callable name — the app injects both adapters below.\n\n/**\n * Terminal + transient states of a server-owned archive-all job, as surfaced to the UI.\n *\n * - `idle` — nothing enqueued yet (initial / reset state).\n * - `enqueuing` — the enqueue adapter is in flight (job not yet acknowledged).\n * - `in-progress` — the job is enqueued/running; the worker is still draining the category.\n * - `complete` — TERMINAL: the worker fully drained the category's active set.\n * - `incomplete` — TERMINAL: the job stopped without draining everything (e.g. hit its own\n * bound / a non-advanceable card). The tray keeps a \"some remain — try again\"\n * affordance, mirroring the old loop's incomplete result.\n * - `failed` — TERMINAL: the enqueue call threw, or the job dead-lettered / reported failure.\n */\nexport type ArchiveAllJobStatus =\n 'idle' | 'enqueuing' | 'in-progress' | 'complete' | 'incomplete' | 'failed';\n\n/**\n * Result of the INJECTED enqueue adapter — triggers exactly one server-owned archive-all job for\n * the given category and returns immediately with the job's id (idempotent per user+category+request\n * on the app side). The app wires this to its `httpsCallable(functions, 'enqueueArchiveAll')`\n * (or equivalent); the generic package never names the callable.\n */\nexport interface EnqueueArchiveAllResult {\n /** Server job id the poller then polls via the status adapter. */\n jobId: string;\n}\n\n/**\n * Snapshot of a server-owned archive-all job, returned by the INJECTED status-query adapter.\n * The poller maps `state` → {@link ArchiveAllJobStatus} and stops polling on any terminal state.\n * `category` echoes the tab/category the job was enqueued for so the UI can assert per-tab scoping.\n */\nexport interface ArchiveAllJobSnapshot {\n /** Job lifecycle state as owned by the server worker. */\n state: 'in-progress' | 'complete' | 'incomplete' | 'failed';\n /** The notification category/tab this job is scoped to (must match the enqueue category). */\n category: string;\n /** Cards archived so far (monotonic); optional progress for the UI. */\n archived?: number;\n /**\n * On a `complete` job: cards the drain could not archive, which are still in the list. A job\n * completes once it has walked the whole category, so a card that keeps failing on its own does\n * not hold the rest of the category back.\n */\n notArchived?: number;\n /** Human-readable failure reason when `state === 'failed'` (optional). */\n error?: string;\n}\n\n/**\n * Aggregate result the poller resolves with once the job reaches a terminal state.\n * `complete` is the load-bearing completion contract (true ONLY when the whole category was\n * drained), preserved from the old loop so callers gate side effects the same way.\n */\nexport interface ArchiveAllPollResult {\n status: Extract<ArchiveAllJobStatus, 'complete' | 'incomplete' | 'failed'>;\n category: string;\n archived: number;\n /** Cards a complete drain left in the list (each failed on its own); 0 otherwise. */\n notArchived: number;\n complete: boolean;\n error?: string;\n}\n\nexport interface UseArchiveAllNotificationsOptions {\n userId: string;\n category: string;\n /**\n * App-supplied adapter that ENQUEUES one server-owned archive-all job scoped to `category` and\n * returns its `jobId`. The `category` is passed so the app callable can carry the tab/source into\n * the job (per-tab scoping is REQUIRED — the worker archives only that category's active cards).\n * Typically `(category) => enqueueArchiveAll({ category })` over an `httpsCallable`.\n */\n enqueueArchiveAllFn: (category: string) => Promise<EnqueueArchiveAllResult>;\n /**\n * App-supplied adapter that returns the current {@link ArchiveAllJobSnapshot} for a job id — the\n * hook polls it until the job reaches a terminal state. Typically\n * `(jobId) => getArchiveAllStatus({ jobId })` over an `httpsCallable`, or a Firestore read of the\n * job doc. No client Firestore writes.\n */\n getArchiveAllStatusFn: (jobId: string) => Promise<ArchiveAllJobSnapshot>;\n /** Poll interval in ms while the job is in-progress (default 1500). */\n pollIntervalMs?: number;\n /**\n * Max number of status polls before the poller gives up and resolves `incomplete` (guards a job\n * that never reaches a terminal state — default 120, i.e. ~3 min at the default interval).\n */\n maxPolls?: number;\n invalidateKeys?: readonly unknown[][];\n}\n\n// ============================================================================\n// COMPONENT PROP TYPES\n// ============================================================================\n\n/**\n * Per-row actions the list hands to `renderRowAction`. The row itself is inert\n * — every affordance lives in the controls the consumer\n * renders in the slot. `archive` performs the active→history archive for that\n * row; it is present ONLY on the active list (archived history rows cannot be\n * re-archived, so it is absent there).\n */\nexport interface NotificationRowActions {\n /** Archives this row; rejects when the archive fails. */\n archive?: () => Promise<void>;\n /**\n * True while this row is archiving, including a category-wide Clear All. After an\n * archive the server confirmed, it stays true until the row leaves the active list.\n */\n isArchivePending?: boolean;\n}\n\n/**\n * What a list hands its `renderError` slot when its read failed. `hasRows` is true when\n * rows from an earlier read are still on screen above the slot (a failed refresh);\n * `retry` re-reads the displayed page and `retrying` is that read's pending flag.\n */\nexport interface NotificationListErrorState {\n error: Error;\n retry: () => void;\n retrying: boolean;\n hasRows: boolean;\n}\n\nexport interface NotificationEmptyStateProps {\n text?: string;\n}\n\nexport interface NotificationUnreadBadgeProps {\n config: NotificationSystemConfig;\n userId: string;\n category: string;\n refetchInterval?: number;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttt-productions/notification-core",
3
- "version": "0.15.16",
3
+ "version": "0.15.17",
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",
@@ -42,8 +42,8 @@
42
42
  },
43
43
  "peerDependencies": {
44
44
  "@tanstack/react-query": ">=5.0.0",
45
- "@ttt-productions/query-core": "^0.14.15",
46
- "@ttt-productions/ui-core": "^0.11.31",
45
+ "@ttt-productions/query-core": "^0.14.22",
46
+ "@ttt-productions/ui-core": "^0.11.34",
47
47
  "firebase": ">=12.0.0",
48
48
  "react": ">=19.0.0",
49
49
  "react-dom": ">=19.0.0"
@@ -70,8 +70,8 @@
70
70
  },
71
71
  "devDependencies": {
72
72
  "@tanstack/react-query": "^5.0.0",
73
- "@ttt-productions/query-core": "^0.14.15",
74
- "@ttt-productions/ui-core": "^0.11.31",
73
+ "@ttt-productions/query-core": "^0.14.22",
74
+ "@ttt-productions/ui-core": "^0.11.34",
75
75
  "@types/react": "^19.0.0",
76
76
  "@types/react-dom": "^19.0.0",
77
77
  "firebase": "^12.14.0",
@@ -1,5 +0,0 @@
1
- export { NotificationList } from './NotificationList.js';
2
- export { NotificationHistoryList } from './NotificationHistoryList.js';
3
- export { NotificationEmptyState } from './NotificationEmptyState.js';
4
- export { NotificationUnreadBadge } from './NotificationUnreadBadge.js';
5
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/react/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC"}
@@ -1,5 +0,0 @@
1
- export { NotificationList } from './NotificationList.js';
2
- export { NotificationHistoryList } from './NotificationHistoryList.js';
3
- export { NotificationEmptyState } from './NotificationEmptyState.js';
4
- export { NotificationUnreadBadge } from './NotificationUnreadBadge.js';
5
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/react/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC","sourcesContent":["export { NotificationList } from './NotificationList.js';\nexport { NotificationHistoryList } from './NotificationHistoryList.js';\nexport { NotificationEmptyState } from './NotificationEmptyState.js';\nexport { NotificationUnreadBadge } from './NotificationUnreadBadge.js';\n"]}
@@ -1,6 +0,0 @@
1
- export { useActiveNotifications } from './useActiveNotifications.js';
2
- export { useNotificationHistory } from './useNotificationHistory.js';
3
- export { useUnreadCount } from './useUnreadCount.js';
4
- export { useArchiveNotification } from './useArchiveNotification.js';
5
- export { useArchiveAllNotifications } from './useArchiveAllNotifications.js';
6
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC"}
@@ -1,6 +0,0 @@
1
- export { useActiveNotifications } from './useActiveNotifications.js';
2
- export { useNotificationHistory } from './useNotificationHistory.js';
3
- export { useUnreadCount } from './useUnreadCount.js';
4
- export { useArchiveNotification } from './useArchiveNotification.js';
5
- export { useArchiveAllNotifications } from './useArchiveAllNotifications.js';
6
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/react/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC","sourcesContent":["export { useActiveNotifications } from './useActiveNotifications.js';\nexport { useNotificationHistory } from './useNotificationHistory.js';\nexport { useUnreadCount } from './useUnreadCount.js';\nexport { useArchiveNotification } from './useArchiveNotification.js';\nexport { useArchiveAllNotifications } from './useArchiveAllNotifications.js';\n"]}