@codingfactory/notify-kit-client 0.2.2 → 0.2.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.
@@ -9,6 +9,7 @@ function createInitialState() {
9
9
  notificationsMeta: null,
10
10
  unreadCount: 0,
11
11
  unreadCountLoading: false,
12
+ lastRealtimeIncrementAt: 0,
12
13
  modalQueue: [],
13
14
  modalsLoading: false,
14
15
  broadcastChannel: null,
@@ -69,6 +70,7 @@ function createStoreReturn(state) {
69
70
  },
70
71
  incrementUnreadCount: () => {
71
72
  state.unreadCount += 1;
73
+ state.lastRealtimeIncrementAt = Date.now();
72
74
  },
73
75
  decrementUnreadCount: () => {
74
76
  if (state.unreadCount > 0) {
@@ -231,5 +233,5 @@ function useNotifyKitModals(options) {
231
233
  }
232
234
 
233
235
  export { InvalidSnoozeDurationError, NOTIFY_KIT_MODALS_KEY, NOTIFY_KIT_STORE_KEY, provideNotifyKitModals, provideNotifyKitStore, resetNotifyKitStore, useNotifyKitModals, useNotifyKitStore };
234
- //# sourceMappingURL=chunk-7LQBNDRD.js.map
235
- //# sourceMappingURL=chunk-7LQBNDRD.js.map
236
+ //# sourceMappingURL=chunk-GBBCD3P6.js.map
237
+ //# sourceMappingURL=chunk-GBBCD3P6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/composables/useNotifyKitStore.ts","../src/composables/useNotifyKitModals.ts"],"names":["provide","computed"],"mappings":"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","file":"chunk-GBBCD3P6.js","sourcesContent":["/**\n * useNotifyKitStore composable\n *\n * Provides a reactive store for NotifyKit state management.\n * Manages notifications, unread counts, modal queue, and connection state.\n * Uses singleton pattern to share state across components.\n */\n\nimport { reactive, readonly, computed, provide, type InjectionKey, type ComputedRef } from 'vue';\nimport type { NotifyKitNotification, PaginationMeta } from '../types';\n\n/**\n * Connection state for real-time subscriptions.\n */\nexport type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'error';\n\n/**\n * Store state shape.\n */\nexport interface NotifyKitStoreState {\n // Notifications\n readonly notifications: readonly NotifyKitNotification[];\n readonly notificationsLoading: boolean;\n readonly notificationsMeta: PaginationMeta | null;\n\n // Unread\n readonly unreadCount: number;\n readonly unreadCountLoading: boolean;\n readonly lastRealtimeIncrementAt: number;\n\n // Modals\n readonly modalQueue: readonly NotifyKitNotification[];\n readonly modalsLoading: boolean;\n\n // Connection\n readonly broadcastChannel: string | null;\n readonly connectionState: ConnectionState;\n\n // Sync timestamps\n readonly lastNotificationsSync: number | null;\n readonly lastModalsSync: number | null;\n}\n\n/**\n * Internal mutable state shape.\n */\ninterface MutableStoreState {\n notifications: NotifyKitNotification[];\n notificationsLoading: boolean;\n notificationsMeta: PaginationMeta | null;\n unreadCount: number;\n unreadCountLoading: boolean;\n lastRealtimeIncrementAt: number;\n modalQueue: NotifyKitNotification[];\n modalsLoading: boolean;\n broadcastChannel: string | null;\n connectionState: ConnectionState;\n lastNotificationsSync: number | null;\n lastModalsSync: number | null;\n}\n\n/**\n * Return type of useNotifyKitStore composable.\n */\nexport interface UseNotifyKitStoreReturn {\n /** Readonly reactive state */\n readonly state: NotifyKitStoreState;\n\n /** Computed: whether there are unread notifications */\n readonly hasUnread: ComputedRef<boolean>;\n\n /** Computed: the current (first) modal in queue, or null */\n readonly currentModal: ComputedRef<NotifyKitNotification | null>;\n\n /** Computed: whether there are modals in the queue */\n readonly hasModals: ComputedRef<boolean>;\n\n // Notification mutations\n addNotification: (notification: NotifyKitNotification) => void;\n setNotifications: (notifications: readonly NotifyKitNotification[]) => void;\n markNotificationRead: (id: string) => void;\n removeNotification: (id: string) => void;\n\n // Unread count mutations\n setUnreadCount: (count: number) => void;\n incrementUnreadCount: () => void;\n decrementUnreadCount: () => void;\n\n // Modal queue mutations\n enqueueModal: (notification: NotifyKitNotification) => void;\n dequeueModal: (id: string) => void;\n clearModalQueue: () => void;\n\n // Connection mutations\n setConnectionState: (state: ConnectionState) => void;\n setBroadcastChannel: (channel: string) => void;\n\n // Loading state mutations\n setNotificationsLoading: (loading: boolean) => void;\n setUnreadCountLoading: (loading: boolean) => void;\n setModalsLoading: (loading: boolean) => void;\n\n // Meta mutations\n setNotificationsMeta: (meta: PaginationMeta | null) => void;\n\n // Sync timestamp mutations\n setLastNotificationsSync: (timestamp: number | null) => void;\n setLastModalsSync: (timestamp: number | null) => void;\n\n // Reset\n reset: () => void;\n}\n\n/**\n * Injection key for the NotifyKit store.\n */\nexport const NOTIFY_KIT_STORE_KEY: InjectionKey<UseNotifyKitStoreReturn> = Symbol('notify-kit-store');\n\n/**\n * Creates the initial store state.\n */\nfunction createInitialState(): MutableStoreState {\n return {\n notifications: [],\n notificationsLoading: false,\n notificationsMeta: null,\n unreadCount: 0,\n unreadCountLoading: false,\n lastRealtimeIncrementAt: 0,\n modalQueue: [],\n modalsLoading: false,\n broadcastChannel: null,\n connectionState: 'disconnected',\n lastNotificationsSync: null,\n lastModalsSync: null,\n };\n}\n\n// Singleton store state\nlet storeState: MutableStoreState | null = null;\n\n/**\n * Gets or creates the singleton store state.\n */\nfunction getStoreState(): MutableStoreState {\n storeState ??= reactive(createInitialState());\n return storeState;\n}\n\n/**\n * Resets the store state to initial values.\n * Primarily used for testing to ensure clean state between tests.\n */\nexport function resetNotifyKitStore(): void {\n if (storeState !== null) {\n Object.assign(storeState, createInitialState());\n }\n}\n\n/**\n * Creates the store return object with all actions and computed properties.\n */\nfunction createStoreReturn(state: MutableStoreState): UseNotifyKitStoreReturn {\n // Computed properties\n const hasUnread = computed(() => state.unreadCount > 0);\n const currentModal = computed(() => state.modalQueue[0] ?? null);\n const hasModals = computed(() => state.modalQueue.length > 0);\n\n return {\n // State as readonly\n state: readonly(state) as NotifyKitStoreState,\n\n // Computed\n hasUnread,\n currentModal,\n hasModals,\n\n // Notification mutations\n addNotification: (notification: NotifyKitNotification): void => {\n state.notifications.unshift(notification);\n },\n\n setNotifications: (notifications: readonly NotifyKitNotification[]): void => {\n state.notifications = [...notifications];\n },\n\n markNotificationRead: (id: string): void => {\n const index = state.notifications.findIndex((n) => n.id === id);\n if (index !== -1) {\n const notification = state.notifications[index];\n if (notification !== undefined) {\n state.notifications[index] = {\n ...notification,\n read_at: new Date().toISOString(),\n };\n }\n }\n },\n\n removeNotification: (id: string): void => {\n const index = state.notifications.findIndex((n) => n.id === id);\n if (index !== -1) {\n state.notifications.splice(index, 1);\n }\n },\n\n // Unread count mutations\n setUnreadCount: (count: number): void => {\n state.unreadCount = count;\n },\n\n incrementUnreadCount: (): void => {\n state.unreadCount += 1;\n state.lastRealtimeIncrementAt = Date.now();\n },\n\n decrementUnreadCount: (): void => {\n if (state.unreadCount > 0) {\n state.unreadCount -= 1;\n }\n },\n\n // Modal queue mutations\n enqueueModal: (notification: NotifyKitNotification): void => {\n // Don't add duplicates\n const exists = state.modalQueue.some((m) => m.id === notification.id);\n if (!exists) {\n state.modalQueue.push(notification);\n }\n },\n\n dequeueModal: (id: string): void => {\n const index = state.modalQueue.findIndex((m) => m.id === id);\n if (index !== -1) {\n state.modalQueue.splice(index, 1);\n }\n },\n\n clearModalQueue: (): void => {\n state.modalQueue = [];\n },\n\n // Connection mutations\n setConnectionState: (connectionState: ConnectionState): void => {\n state.connectionState = connectionState;\n },\n\n setBroadcastChannel: (channel: string): void => {\n state.broadcastChannel = channel;\n },\n\n // Loading state mutations\n setNotificationsLoading: (loading: boolean): void => {\n state.notificationsLoading = loading;\n },\n\n setUnreadCountLoading: (loading: boolean): void => {\n state.unreadCountLoading = loading;\n },\n\n setModalsLoading: (loading: boolean): void => {\n state.modalsLoading = loading;\n },\n\n // Meta mutations\n setNotificationsMeta: (meta: PaginationMeta | null): void => {\n state.notificationsMeta = meta;\n },\n\n // Sync timestamp mutations\n setLastNotificationsSync: (timestamp: number | null): void => {\n state.lastNotificationsSync = timestamp;\n },\n\n setLastModalsSync: (timestamp: number | null): void => {\n state.lastModalsSync = timestamp;\n },\n\n // Reset\n reset: (): void => {\n Object.assign(state, createInitialState());\n },\n };\n}\n\n/**\n * Provides the NotifyKit store for injection into descendant components.\n *\n * Call this in your app's setup or a parent component to make the store\n * available to all child components via useNotifyKitStore().\n *\n * @example\n * ```typescript\n * // In App.vue setup\n * const store = provideNotifyKitStore()\n *\n * // In any child component\n * const { state, addNotification } = useNotifyKitStore()\n * ```\n */\nexport function provideNotifyKitStore(): UseNotifyKitStoreReturn {\n const state = getStoreState();\n const store = createStoreReturn(state);\n provide(NOTIFY_KIT_STORE_KEY, store);\n return store;\n}\n\n/**\n * Access the NotifyKit store within a Vue component.\n *\n * Uses a singleton pattern to share state across all components.\n *\n * @example\n * ```typescript\n * const {\n * state,\n * hasUnread,\n * currentModal,\n * addNotification,\n * markNotificationRead\n * } = useNotifyKitStore()\n * ```\n */\nexport function useNotifyKitStore(): UseNotifyKitStoreReturn {\n const state = getStoreState();\n return createStoreReturn(state);\n}\n","/**\n * useNotifyKitModals composable\n *\n * Provides modal queue management for critical notifications.\n * Handles loading outstanding modals, acknowledgement, and snoozing.\n */\n\nimport { computed, provide, type ComputedRef, type InjectionKey, type Ref } from 'vue';\nimport { useNotifyKitStore } from './useNotifyKitStore';\nimport type { NotifyKitNotification } from '../types';\n\n/**\n * Minimal NotifyKit client interface - just the modal methods.\n */\nexport interface NotifyKitModalsClientLike {\n listModals: () => Promise<readonly NotifyKitNotification[]>;\n ackModal: (id: string) => Promise<void>;\n snoozeModal: (id: string, minutes: number) => Promise<void>;\n}\n\n/**\n * Configuration options for useNotifyKitModals.\n */\nexport interface UseNotifyKitModalsOptions {\n /**\n * NotifyKit client instance for modal API calls.\n */\n client: NotifyKitModalsClientLike;\n}\n\n/**\n * Return type of useNotifyKitModals composable.\n */\nexport interface UseNotifyKitModalsReturn {\n /** The current (first) modal in queue, or null */\n readonly currentModal: ComputedRef<NotifyKitNotification | null>;\n\n /** All modals in the queue */\n readonly modalQueue: ComputedRef<readonly NotifyKitNotification[]>;\n\n /** Whether there are modals in the queue */\n readonly hasModals: ComputedRef<boolean>;\n\n /** Whether modals are currently being loaded */\n readonly isLoading: Ref<boolean>;\n\n /** Load outstanding modals from the API */\n loadOutstandingModals: () => Promise<void>;\n\n /** Acknowledge a modal (removes from queue) */\n ack: (id: string) => Promise<void>;\n\n /** Snooze a modal (removes from queue temporarily) */\n snooze: (id: string, minutes: number) => Promise<void>;\n\n /** Acknowledge the current modal */\n dismissCurrent: () => Promise<void>;\n\n /** Snooze the current modal */\n snoozeCurrent: (minutes: number) => Promise<void>;\n\n /** Get allowed snooze options for a notification */\n getSnoozeOptions: (notification: NotifyKitNotification) => readonly number[];\n}\n\n/**\n * Error thrown when an invalid snooze duration is provided.\n */\nexport class InvalidSnoozeDurationError extends Error {\n public override readonly name = 'InvalidSnoozeDurationError';\n\n constructor(minutes: number, allowedMinutes: readonly number[]) {\n super(`Invalid snooze duration: ${String(minutes)}. Allowed values: ${allowedMinutes.join(', ')}`);\n }\n}\n\n/**\n * Injection key for the NotifyKit modals composable.\n */\nexport const NOTIFY_KIT_MODALS_KEY: InjectionKey<UseNotifyKitModalsReturn> = Symbol('notify-kit-modals');\n\n/**\n * Provides NotifyKit modals management for injection into descendant components.\n *\n * @example\n * ```typescript\n * // In App.vue setup\n * const modals = provideNotifyKitModals({ client })\n *\n * // In any child component\n * const { currentModal, dismissCurrent } = useNotifyKitModals({ client })\n * ```\n */\nexport function provideNotifyKitModals(options: UseNotifyKitModalsOptions): UseNotifyKitModalsReturn {\n const modals = useNotifyKitModals(options);\n provide(NOTIFY_KIT_MODALS_KEY, modals);\n return modals;\n}\n\n/**\n * Composable for managing modal notification queue.\n *\n * Handles loading outstanding modals from the API, acknowledging them,\n * and snoozing them. Uses the store for reactive queue management.\n *\n * @example\n * ```typescript\n * const {\n * currentModal,\n * hasModals,\n * loadOutstandingModals,\n * dismissCurrent,\n * snoozeCurrent,\n * getSnoozeOptions\n * } = useNotifyKitModals({ client })\n *\n * // Load modals on login\n * await loadOutstandingModals()\n *\n * // Handle current modal\n * if (currentModal.value) {\n * const options = getSnoozeOptions(currentModal.value)\n * // Show modal with snooze options...\n * }\n *\n * // User acknowledges\n * await dismissCurrent()\n *\n * // Or user snoozes for 1 hour\n * await snoozeCurrent(60)\n * ```\n */\nexport function useNotifyKitModals(options: UseNotifyKitModalsOptions): UseNotifyKitModalsReturn {\n const { client } = options;\n\n // Get the store for state management\n const store = useNotifyKitStore();\n\n // Computed properties from store\n const currentModal = computed(() => store.currentModal.value);\n const modalQueue = computed(() => store.state.modalQueue);\n const hasModals = computed(() => store.hasModals.value);\n const isLoading = computed(() => store.state.modalsLoading);\n\n /**\n * Load outstanding modals from the API and enqueue them.\n */\n async function loadOutstandingModals(): Promise<void> {\n store.setModalsLoading(true);\n\n try {\n const modals = await client.listModals();\n\n for (const modal of modals) {\n store.enqueueModal(modal);\n }\n\n store.setLastModalsSync(Date.now());\n } finally {\n store.setModalsLoading(false);\n }\n }\n\n /**\n * Find a modal in the queue by ID.\n */\n function findModal(id: string): NotifyKitNotification | undefined {\n return store.state.modalQueue.find((m) => m.id === id);\n }\n\n /**\n * Acknowledge a modal.\n */\n async function ack(id: string): Promise<void> {\n const modal = findModal(id);\n if (modal === undefined) {\n return;\n }\n\n // Optimistically remove from queue\n store.dequeueModal(id);\n\n try {\n await client.ackModal(id);\n } catch (error) {\n // Re-enqueue on failure\n store.enqueueModal(modal);\n throw error;\n }\n }\n\n /**\n * Snooze a modal.\n */\n async function snooze(id: string, minutes: number): Promise<void> {\n const modal = findModal(id);\n if (modal === undefined) {\n return;\n }\n\n // Validate minutes against allowed options\n const allowedOptions = getSnoozeOptions(modal);\n if (!allowedOptions.includes(minutes)) {\n throw new InvalidSnoozeDurationError(minutes, allowedOptions);\n }\n\n // Optimistically remove from queue\n store.dequeueModal(id);\n\n try {\n await client.snoozeModal(id, minutes);\n } catch (error) {\n // Re-enqueue on failure\n store.enqueueModal(modal);\n throw error;\n }\n }\n\n /**\n * Acknowledge the current modal.\n */\n async function dismissCurrent(): Promise<void> {\n const current = currentModal.value;\n if (current === null) {\n return;\n }\n\n await ack(current.id);\n }\n\n /**\n * Snooze the current modal.\n */\n async function snoozeCurrent(minutes: number): Promise<void> {\n const current = currentModal.value;\n if (current === null) {\n return;\n }\n\n await snooze(current.id, minutes);\n }\n\n /**\n * Get allowed snooze options for a notification.\n */\n function getSnoozeOptions(notification: NotifyKitNotification): readonly number[] {\n return notification.modal?.snooze_options_minutes ?? [];\n }\n\n return {\n currentModal,\n modalQueue,\n hasModals,\n isLoading,\n loadOutstandingModals,\n ack,\n snooze,\n dismissCurrent,\n snoozeCurrent,\n getSnoozeOptions,\n };\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { N as NotifyKitNotification, a as NotifyKitClient, b as NotifyKitMeResponse, L as ListNotificationsParams, c as NotifyKitListResponse, d as NotifyKitUnreadCountResponse, e as NotifyKitReadMutationResponse, P as PaginationParams, f as NotifyKitPreferenceSettingsQuery, g as NotifyKitPreferences, h as NotifyKitPreferencesUpdate, i as NotifyKitClientConfig, C as ConnectionState, B as BulkActionResult, j as BulkFilters, S as SearchFilters, k as SavedFilter, l as NotificationCategory, m as NotificationLevel } from './useNotifyKitModals-CWHM9rYY.js';
2
- export { n as BulkActionRequest, I as InvalidSnoozeDurationError, o as NOTIFICATION_CATEGORIES, p as NOTIFICATION_LEVELS, q as NOTIFY_KIT_MODALS_KEY, r as NOTIFY_KIT_STORE_KEY, s as NotifyKitApiError, t as NotifyKitDigestPreferences, u as NotifyKitErrorResponse, v as NotifyKitGroupedEntry, w as NotifyKitGroupedListResponse, x as NotifyKitModalSpec, y as NotifyKitModalState, z as NotifyKitModalsClientLike, A as NotifyKitModalsResponse, D as NotifyKitMutationResponse, E as NotifyKitPreferenceBooleanMap, F as NotifyKitPreferenceModeMap, G as NotifyKitPreferenceSettings, H as NotifyKitPreferenceSettingsUpdate, J as NotifyKitSingleNotificationResponse, K as NotifyKitStoreState, M as PaginationMeta, O as SavedFiltersResponse, Q as SearchResult, U as UseNotifyKitModalsOptions, R as UseNotifyKitModalsReturn, T as UseNotifyKitStoreReturn, V as createNotifyKitClient, W as isMeResponse, X as isModalEnabled, Y as isModalSpec, Z as isNotifyKitNotification, _ as isNotifyKitPreferenceSettings, $ as isNotifyKitQuietHours, a0 as isPaginationMeta, a1 as isUnreadCountResponse, a2 as isValidCategory, a3 as isValidLevel, a4 as provideNotifyKitModals, a5 as provideNotifyKitStore, a6 as resetNotifyKitStore, a7 as useNotifyKitModals, a8 as useNotifyKitStore } from './useNotifyKitModals-CWHM9rYY.js';
1
+ import { N as NotifyKitNotification, a as NotifyKitClient, b as NotifyKitMeResponse, L as ListNotificationsParams, c as NotifyKitListResponse, d as NotifyKitUnreadCountResponse, e as NotifyKitReadMutationResponse, P as PaginationParams, f as NotifyKitPreferenceSettingsQuery, g as NotifyKitPreferences, h as NotifyKitPreferencesUpdate, i as NotifyKitClientConfig, C as ConnectionState, B as BulkActionResult, j as BulkFilters, S as SearchFilters, k as SavedFilter, l as NotificationCategory, m as NotificationLevel } from './useNotifyKitModals-DFF8yJeq.js';
2
+ export { n as BulkActionRequest, I as InvalidSnoozeDurationError, o as NOTIFICATION_CATEGORIES, p as NOTIFICATION_LEVELS, q as NOTIFY_KIT_MODALS_KEY, r as NOTIFY_KIT_STORE_KEY, s as NotifyKitApiError, t as NotifyKitDigestPreferences, u as NotifyKitErrorResponse, v as NotifyKitGroupedEntry, w as NotifyKitGroupedListResponse, x as NotifyKitModalSpec, y as NotifyKitModalState, z as NotifyKitModalsClientLike, A as NotifyKitModalsResponse, D as NotifyKitMutationResponse, E as NotifyKitPreferenceBooleanMap, F as NotifyKitPreferenceModeMap, G as NotifyKitPreferenceSettings, H as NotifyKitPreferenceSettingsUpdate, J as NotifyKitSingleNotificationResponse, K as NotifyKitStoreState, M as PaginationMeta, O as SavedFiltersResponse, Q as SearchResult, U as UseNotifyKitModalsOptions, R as UseNotifyKitModalsReturn, T as UseNotifyKitStoreReturn, V as createNotifyKitClient, W as isMeResponse, X as isModalEnabled, Y as isModalSpec, Z as isNotifyKitNotification, _ as isNotifyKitPreferenceSettings, $ as isNotifyKitQuietHours, a0 as isPaginationMeta, a1 as isUnreadCountResponse, a2 as isValidCategory, a3 as isValidLevel, a4 as provideNotifyKitModals, a5 as provideNotifyKitStore, a6 as resetNotifyKitStore, a7 as useNotifyKitModals, a8 as useNotifyKitStore } from './useNotifyKitModals-DFF8yJeq.js';
3
3
  import { InjectionKey, ComputedRef, Ref } from 'vue';
4
4
 
5
5
  declare function normalizeApiNotification(raw: unknown): NotifyKitNotification;
@@ -130,6 +130,7 @@ interface NotifyKitInboxClientLike {
130
130
  interface UseNotifyKitInboxOptions {
131
131
  client: NotifyKitInboxClientLike;
132
132
  perPage?: number;
133
+ grouped?: boolean;
133
134
  }
134
135
  interface UseNotifyKitInboxReturn {
135
136
  readonly notifications: ComputedRef<readonly NotifyKitNotification[]>;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { useNotifyKitStore } from './chunk-7LQBNDRD.js';
2
- export { InvalidSnoozeDurationError, NOTIFY_KIT_MODALS_KEY, NOTIFY_KIT_STORE_KEY, provideNotifyKitModals, provideNotifyKitStore, resetNotifyKitStore, useNotifyKitModals, useNotifyKitStore } from './chunk-7LQBNDRD.js';
1
+ import { useNotifyKitStore } from './chunk-GBBCD3P6.js';
2
+ export { InvalidSnoozeDurationError, NOTIFY_KIT_MODALS_KEY, NOTIFY_KIT_STORE_KEY, provideNotifyKitModals, provideNotifyKitStore, resetNotifyKitStore, useNotifyKitModals, useNotifyKitStore } from './chunk-GBBCD3P6.js';
3
3
  import { provide, inject, computed, ref, onMounted, onUnmounted, watch, reactive, readonly } from 'vue';
4
4
 
5
5
  // src/types/modal.ts
@@ -198,10 +198,44 @@ function buildUser(payload) {
198
198
  }
199
199
  return user;
200
200
  }
201
+ function isGroupedEntry(value) {
202
+ if (!isRecord(value)) {
203
+ return false;
204
+ }
205
+ return typeof value["group_key"] === "string" && isRecord(value["latest_notification"]);
206
+ }
207
+ function normalizeGroupedEntry(entry) {
208
+ const inner = normalizeApiNotification(entry.latest_notification);
209
+ const groupData = {};
210
+ if (typeof entry["group_count"] === "number") {
211
+ groupData["group_count"] = entry["group_count"];
212
+ }
213
+ if (typeof entry["group_key"] === "string") {
214
+ groupData["group_key"] = entry["group_key"];
215
+ }
216
+ if (Array.isArray(entry["notification_ids"])) {
217
+ groupData["notification_ids"] = entry["notification_ids"];
218
+ }
219
+ if (typeof entry["has_unread"] === "boolean") {
220
+ groupData["has_unread"] = entry["has_unread"];
221
+ }
222
+ return {
223
+ ...inner,
224
+ group_key: nullableString(entry["group_key"]) ?? inner.group_key,
225
+ read_at: entry["has_unread"] === false ? inner.read_at ?? (/* @__PURE__ */ new Date()).toISOString() : inner.read_at,
226
+ data: {
227
+ ...inner.data,
228
+ ...groupData
229
+ }
230
+ };
231
+ }
201
232
  function normalizeApiNotification(raw) {
202
233
  if (isNotifyKitNotification(raw)) {
203
234
  return raw;
204
235
  }
236
+ if (isGroupedEntry(raw)) {
237
+ return normalizeGroupedEntry(raw);
238
+ }
205
239
  const rawRecord = isRecord(raw) ? {
206
240
  id: stringOrFallback(raw["id"], ""),
207
241
  type: nullableString(raw["type"]) ?? void 0,
@@ -786,7 +820,7 @@ function asNotifyKitApiError(error) {
786
820
  };
787
821
  }
788
822
  function useNotifyKitInbox(options) {
789
- const { client, perPage = DEFAULT_PER_PAGE } = options;
823
+ const { client, perPage = DEFAULT_PER_PAGE, grouped } = options;
790
824
  const store = useNotifyKitStore();
791
825
  const state = getInboxState();
792
826
  const notifications = computed(() => store.state.notifications);
@@ -819,9 +853,17 @@ function useNotifyKitInbox(options) {
819
853
  return true;
820
854
  }
821
855
  store.setUnreadCountLoading(true);
856
+ const requestStartedAt = Date.now();
822
857
  state.unreadCountRequest = (async () => {
823
858
  try {
824
859
  const response = await client.getUnreadCount();
860
+ const realtimeIncrementDuringRequest = store.state.lastRealtimeIncrementAt >= requestStartedAt;
861
+ if (realtimeIncrementDuringRequest && response.count < store.state.unreadCount) {
862
+ state.unreadCountLastLoadedAt = Date.now();
863
+ state.unreadCountTransientFailureCount = 0;
864
+ state.unreadCountRetryAfterUntil = 0;
865
+ return true;
866
+ }
825
867
  store.setUnreadCount(response.count);
826
868
  state.unreadCountLastLoadedAt = Date.now();
827
869
  state.unreadCountTransientFailureCount = 0;
@@ -868,7 +910,8 @@ function useNotifyKitInbox(options) {
868
910
  const pageNumber = page !== null ? Number(page) : 1;
869
911
  const response = await client.listNotifications({
870
912
  per_page: perPage,
871
- page: pageNumber
913
+ page: pageNumber,
914
+ ...grouped === true ? { grouped: true } : {}
872
915
  });
873
916
  const items = [...response.data];
874
917
  if (append) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types/modal.ts","../src/types/notification.ts","../src/types/preferences.ts","../src/types/api.ts","../src/client/normalizeNotification.ts","../src/client/NotifyKitClient.ts","../src/client/endpoints.ts","../src/composables/useNotifyKitClient.ts","../src/composables/useNotifyKitInbox.ts","../src/composables/useNotifyKitRealtimeState.ts","../src/helpers/toastPolicy.ts","../src/helpers/notifyKitRealtimeChannel.ts","../src/composables/useNotifyKitRealtime.ts","../src/composables/useNotifyKitFallback.ts","../src/composables/useNotifyKitBulkActions.ts","../src/composables/useNotifyKitSearch.ts","../src/index.ts"],"names":["error","isRecord","computed","ref","onUnmounted","reactive","createInitialState","readonly"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Modal-related type definitions for critical notification modals.\n */\n\n/**\n * Modal specification included in notifications that require modal display.\n */\nexport interface NotifyKitModalSpec {\n /** Whether modal display is enabled for this notification */\n readonly enabled: boolean;\n\n /** Whether the user must acknowledge before dismissing */\n readonly requires_ack: boolean;\n\n /** Available snooze duration options in minutes */\n readonly snooze_options_minutes: readonly number[];\n}\n\n/**\n * Modal state tracking for a notification.\n * This represents the user's interaction state with a modal notification.\n */\nexport interface NotifyKitModalState {\n /** Timestamp when the modal was acknowledged (ISO 8601), null if not yet acknowledged */\n readonly acknowledged_at: string | null;\n\n /** Timestamp until which the modal is snoozed (ISO 8601), null if not snoozed */\n readonly snoozed_until: string | null;\n}\n\n/**\n * Type guard to validate if a value is a valid NotifyKitModalSpec.\n */\nexport function isModalSpec(value: unknown): value is NotifyKitModalSpec {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const obj = value as Record<string, unknown>;\n\n if (typeof obj['enabled'] !== 'boolean') return false;\n if (typeof obj['requires_ack'] !== 'boolean') return false;\n if (!Array.isArray(obj['snooze_options_minutes'])) return false;\n\n // Validate all snooze options are positive integers\n const snoozeOptions = obj['snooze_options_minutes'] as unknown[];\n for (const option of snoozeOptions) {\n if (typeof option !== 'number' || !Number.isInteger(option) || option < 1) {\n return false;\n }\n }\n\n return true;\n}\n","/**\n * Notification type definitions matching the Notify Kit backend contract.\n */\n\nimport type { NotifyKitModalSpec } from './modal';\nimport { isModalSpec } from './modal';\n\n/**\n * Valid notification categories.\n */\nexport type NotificationCategory =\n | 'workspace'\n | 'security'\n | 'orders'\n | 'social'\n | 'system'\n | 'marketing';\n\n/**\n * Valid notification severity levels.\n */\nexport type NotificationLevel = 'info' | 'success' | 'warning' | 'danger';\n\n/**\n * All valid category values for runtime validation.\n */\nexport const NOTIFICATION_CATEGORIES: readonly NotificationCategory[] = [\n 'workspace',\n 'security',\n 'orders',\n 'social',\n 'system',\n 'marketing',\n] as const;\n\n/**\n * All valid level values for runtime validation.\n */\nexport const NOTIFICATION_LEVELS: readonly NotificationLevel[] = [\n 'info',\n 'success',\n 'warning',\n 'danger',\n] as const;\n\n/**\n * Core notification payload structure matching the Notify Kit backend contract.\n */\nexport interface NotifyKitNotification {\n /** Unique notification ID (UUID) */\n readonly id: string;\n\n /** Notification key (e.g., 'orders.shipped', 'security.critical_alert') */\n readonly key: string;\n\n /** Notification category */\n readonly category: NotificationCategory;\n\n /** Severity level */\n readonly level: NotificationLevel;\n\n /** Notification title */\n readonly title: string;\n\n /** Notification body text */\n readonly body: string;\n\n /** Optional URL for the notification action */\n readonly action_url: string | null;\n\n /** Workspace ID if this is a workspace-scoped notification */\n readonly workspace_id: string | null;\n\n /** Modal specification if this notification requires modal display */\n readonly modal: NotifyKitModalSpec | null;\n\n /** Group key for notification aggregation (Phase 2) */\n readonly group_key: string | null;\n\n /** Idempotency key to prevent duplicate notifications (Phase 2) */\n readonly idempotency_key: string | null;\n\n /** Additional arbitrary data */\n readonly data: Record<string, unknown>;\n\n /** Timestamp when notification was marked as read (ISO 8601) */\n readonly read_at: string | null;\n\n /** Timestamp when notification was created (ISO 8601) */\n readonly created_at: string;\n}\n\n/**\n * Type guard to validate if a value is a valid NotificationCategory.\n */\nexport function isValidCategory(value: unknown): value is NotificationCategory {\n return (\n typeof value === 'string' &&\n (NOTIFICATION_CATEGORIES as readonly string[]).includes(value)\n );\n}\n\n/**\n * Type guard to validate if a value is a valid NotificationLevel.\n */\nexport function isValidLevel(value: unknown): value is NotificationLevel {\n return (\n typeof value === 'string' && (NOTIFICATION_LEVELS as readonly string[]).includes(value)\n );\n}\n\n/**\n * Type guard to validate if a value is a NotifyKitNotification.\n * Use this to validate data from external sources (API responses, WebSocket messages).\n */\nexport function isNotifyKitNotification(value: unknown): value is NotifyKitNotification {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const obj = value as Record<string, unknown>;\n\n // Check required string fields\n if (typeof obj['id'] !== 'string') return false;\n if (typeof obj['key'] !== 'string') return false;\n if (typeof obj['title'] !== 'string') return false;\n if (typeof obj['body'] !== 'string') return false;\n if (typeof obj['created_at'] !== 'string') return false;\n\n // Check category and level enums\n if (!isValidCategory(obj['category'])) return false;\n if (!isValidLevel(obj['level'])) return false;\n\n // Check nullable string fields (must be string or null)\n if (obj['action_url'] !== null && typeof obj['action_url'] !== 'string') return false;\n if (obj['workspace_id'] !== null && typeof obj['workspace_id'] !== 'string') return false;\n if (obj['group_key'] !== null && typeof obj['group_key'] !== 'string') return false;\n if (obj['idempotency_key'] !== null && typeof obj['idempotency_key'] !== 'string')\n return false;\n if (obj['read_at'] !== null && typeof obj['read_at'] !== 'string') return false;\n\n // Check data is an object\n if (typeof obj['data'] !== 'object' || obj['data'] === null) {\n // data might be an empty object or missing, default to checking it's object-like\n if (obj['data'] !== undefined && (typeof obj['data'] !== 'object' || obj['data'] === null)) {\n return false;\n }\n }\n\n // Check modal is null or valid NotifyKitModalSpec\n if (obj['modal'] !== null && !isModalSpec(obj['modal'])) return false;\n\n return true;\n}\n\n/**\n * Helper to check if a notification has modal functionality enabled.\n */\nexport function isModalEnabled(notification: NotifyKitNotification): boolean {\n return notification.modal?.enabled ?? false;\n}\n","/**\n * User notification preference settings type definitions.\n */\n\nimport type { NotificationCategory } from './notification';\n\nexport type NotifyKitPreferenceBooleanMap = Readonly<Record<string, boolean>>;\n\nexport type NotifyKitPreferenceModeMap = Readonly<Record<string, string>>;\n\nexport interface NotifyKitQuietHours {\n readonly start: string;\n readonly end: string;\n}\n\nexport interface NotifyKitDigestPreferences {\n readonly enabled: boolean;\n readonly frequency: 'daily' | 'weekly';\n readonly categories: readonly NotificationCategory[] | null;\n readonly workspace_id: string | null;\n readonly timezone: string | null;\n readonly hour: number;\n readonly quiet_hours: NotifyKitQuietHours | null;\n}\n\nexport interface NotifyKitPreferenceSettings {\n readonly channels: NotifyKitPreferenceBooleanMap;\n readonly channel_modes: NotifyKitPreferenceModeMap;\n readonly topics: NotifyKitPreferenceBooleanMap;\n readonly email_preferences: NotifyKitPreferenceBooleanMap;\n readonly keyword_rules: readonly string[];\n readonly digest: NotifyKitDigestPreferences;\n readonly available_channels: readonly string[];\n readonly available_topics: readonly string[];\n readonly available_email_preferences: readonly string[];\n}\n\nexport interface NotifyKitPreferenceSettingsQuery {\n readonly workspace_id?: string | null;\n}\n\nexport interface NotifyKitPreferenceSettingsUpdate {\n readonly workspace_id?: string | null;\n readonly channels?: Record<string, boolean>;\n readonly channel_modes?: Record<string, string>;\n readonly topics?: Record<string, boolean>;\n readonly email_preferences?: Record<string, boolean>;\n readonly keyword_rules?: readonly string[];\n readonly digest?: {\n readonly enabled?: boolean;\n readonly frequency?: 'daily' | 'weekly';\n readonly categories?: readonly NotificationCategory[] | null;\n readonly timezone?: string | null;\n readonly hour?: number;\n readonly quiet_hours?: NotifyKitQuietHours | null;\n };\n}\n\nexport type NotifyKitPreferences = NotifyKitPreferenceSettings;\n\nexport type NotifyKitPreferencesUpdate = NotifyKitPreferenceSettingsUpdate;\n\nfunction isBooleanRecord(value: unknown): value is Record<string, boolean> {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n return Object.values(value).every((entry) => typeof entry === 'boolean');\n}\n\nfunction isStringRecord(value: unknown): value is Record<string, string> {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n return Object.values(value).every((entry) => typeof entry === 'string');\n}\n\nfunction isStringArray(value: unknown): value is readonly string[] {\n return Array.isArray(value) && value.every((entry) => typeof entry === 'string');\n}\n\nexport function isNotifyKitQuietHours(value: unknown): value is NotifyKitQuietHours {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const obj = value as Record<string, unknown>;\n\n return typeof obj['start'] === 'string' && typeof obj['end'] === 'string';\n}\n\nexport function isNotifyKitPreferenceSettings(\n value: unknown\n): value is NotifyKitPreferenceSettings {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const obj = value as Record<string, unknown>;\n const digest = obj['digest'];\n\n if (typeof digest !== 'object' || digest === null) {\n return false;\n }\n\n const digestRecord = digest as Record<string, unknown>;\n const quietHours = digestRecord['quiet_hours'];\n const categories = digestRecord['categories'];\n\n return (\n isBooleanRecord(obj['channels']) &&\n isStringRecord(obj['channel_modes']) &&\n isBooleanRecord(obj['topics']) &&\n isBooleanRecord(obj['email_preferences']) &&\n isStringArray(obj['keyword_rules']) &&\n typeof digestRecord['enabled'] === 'boolean' &&\n (digestRecord['frequency'] === 'daily' || digestRecord['frequency'] === 'weekly') &&\n (categories === null || isStringArray(categories)) &&\n (digestRecord['workspace_id'] === null || typeof digestRecord['workspace_id'] === 'string') &&\n (digestRecord['timezone'] === null || typeof digestRecord['timezone'] === 'string') &&\n typeof digestRecord['hour'] === 'number' &&\n (quietHours === null || isNotifyKitQuietHours(quietHours)) &&\n isStringArray(obj['available_channels']) &&\n isStringArray(obj['available_topics']) &&\n isStringArray(obj['available_email_preferences'])\n );\n}\n","/**\n * API response type definitions for Notify Kit endpoints.\n */\n\nimport type { NotifyKitNotification, NotificationCategory } from './notification';\n\n/**\n * Pagination metadata returned with list responses.\n */\nexport interface PaginationMeta {\n /** Current page number (1-indexed) */\n readonly current_page: number;\n\n /** Last page number */\n readonly last_page: number;\n\n /** Number of items per page */\n readonly per_page: number;\n\n /** Total number of items */\n readonly total: number;\n}\n\n/**\n * Response from GET /me endpoint.\n */\nexport interface NotifyKitMeResponse {\n /** The private broadcast channel for this user */\n readonly broadcast_channel: string;\n}\n\n/**\n * Response from GET /notifications endpoint.\n */\nexport interface NotifyKitListResponse {\n /** Array of notifications */\n readonly data: readonly NotifyKitNotification[];\n\n /** Pagination metadata */\n readonly meta: PaginationMeta;\n}\n\n/**\n * A grouped notification entry returned when using grouped=1 parameter.\n */\nexport interface NotifyKitGroupedEntry {\n /** The group key for this group */\n readonly group_key: string;\n\n /** Number of notifications in this group */\n readonly group_count: number;\n\n /** The most recent notification in the group */\n readonly latest_notification: NotifyKitNotification;\n\n /** IDs of all notifications in this group */\n readonly notification_ids: readonly string[];\n\n /** Whether any notification in the group is unread */\n readonly has_unread: boolean;\n}\n\n/**\n * Response from GET /notifications?grouped=1 endpoint.\n */\nexport interface NotifyKitGroupedListResponse {\n /** Array of grouped entries (may include ungrouped notifications as single-item groups) */\n readonly data: readonly NotifyKitGroupedEntry[];\n\n /** Pagination metadata */\n readonly meta: PaginationMeta;\n}\n\n/**\n * Response from GET /notifications/unread-count endpoint.\n */\nexport interface NotifyKitUnreadCountResponse {\n /** Number of unread notifications */\n readonly count: number;\n}\n\n/**\n * Response from GET /modals endpoint.\n */\nexport interface NotifyKitModalsResponse {\n /** Array of outstanding modal notifications */\n readonly data: readonly NotifyKitNotification[];\n}\n\n/**\n * Response from GET /notifications/:id endpoint.\n */\nexport interface NotifyKitSingleNotificationResponse {\n /** The requested notification */\n readonly data: NotifyKitNotification;\n}\n\n/**\n * Generic message response from mutation endpoints.\n */\nexport interface NotifyKitMutationResponse {\n /** Human-readable result message */\n readonly message: string;\n}\n\n/**\n * Response from read actions that also return the updated unread count.\n */\nexport interface NotifyKitReadMutationResponse extends NotifyKitMutationResponse {\n /** Updated unread count when supplied by the backend */\n readonly unread_count?: number;\n}\n\n/**\n * Parameters for listing notifications.\n */\nexport interface ListNotificationsParams {\n /** Filter to unread notifications only */\n readonly unread?: boolean;\n\n /** Filter by category */\n readonly category?: NotificationCategory;\n\n /** Filter by workspace ID */\n readonly workspace_id?: string;\n\n /** Enable grouped mode (Phase 2) */\n readonly grouped?: boolean;\n\n /** Page number for pagination */\n readonly page?: number;\n\n /** Number of items per page */\n readonly per_page?: number;\n}\n\n/**\n * Parameters for paginated requests.\n */\nexport interface PaginationParams {\n /** Page number (1-indexed) */\n readonly page?: number;\n\n /** Number of items per page */\n readonly per_page?: number;\n}\n\n/**\n * Standard error response from the API.\n */\nexport interface NotifyKitErrorResponse {\n /** Error message */\n readonly message: string;\n\n /** Validation errors (field -> error messages) */\n readonly errors?: Readonly<Record<string, readonly string[]>>;\n}\n\n/**\n * Type guard to validate PaginationMeta.\n */\nexport function isPaginationMeta(value: unknown): value is PaginationMeta {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const obj = value as Record<string, unknown>;\n\n return (\n typeof obj['current_page'] === 'number' &&\n typeof obj['last_page'] === 'number' &&\n typeof obj['per_page'] === 'number' &&\n typeof obj['total'] === 'number'\n );\n}\n\n/**\n * Type guard to validate NotifyKitMeResponse.\n */\nexport function isMeResponse(value: unknown): value is NotifyKitMeResponse {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const obj = value as Record<string, unknown>;\n return typeof obj['broadcast_channel'] === 'string';\n}\n\n/**\n * Type guard to validate NotifyKitUnreadCountResponse.\n */\nexport function isUnreadCountResponse(value: unknown): value is NotifyKitUnreadCountResponse {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const obj = value as Record<string, unknown>;\n return typeof obj['count'] === 'number';\n}\n\n// ============================================\n// Bulk Actions\n// ============================================\n\n/**\n * Filters for bulk operations.\n */\nexport interface BulkFilters {\n /** Filter by category */\n readonly category?: NotificationCategory;\n\n /** Filter to unread only */\n readonly unread_only?: boolean;\n}\n\n/**\n * Request body for bulk actions.\n */\nexport interface BulkActionRequest {\n /** Specific notification IDs to act on */\n readonly notification_ids?: readonly string[];\n\n /** Act on all matching notifications */\n readonly all?: boolean;\n\n /** Filters to apply when all=true */\n readonly filters?: BulkFilters;\n}\n\n/**\n * Response from bulk action endpoints.\n */\nexport interface BulkActionResult {\n /** Number of notifications affected */\n readonly affected: number;\n\n /** Number of failures */\n readonly failed: number;\n}\n\n// ============================================\n// Search\n// ============================================\n\n/**\n * Search filters for notification search.\n */\nexport interface SearchFilters {\n /** Filter by category */\n readonly category?: NotificationCategory;\n\n /** Filter to unread only */\n readonly unread?: boolean;\n\n /** Filter by level */\n readonly level?: string;\n}\n\n/**\n * Response from search endpoint.\n */\nexport interface SearchResult {\n /** Array of matching notifications */\n readonly data: readonly NotifyKitNotification[];\n\n /** Total number of matches */\n readonly total: number;\n}\n\n/**\n * A saved filter preset.\n */\nexport interface SavedFilter {\n /** Unique filter ID */\n readonly id: string;\n\n /** Display name */\n readonly name: string;\n\n /** Filter configuration */\n readonly filters: Readonly<Record<string, unknown>>;\n\n /** Whether this is a system-provided preset */\n readonly system: boolean;\n}\n\n/**\n * Response from saved filters endpoint.\n */\nexport interface SavedFiltersResponse {\n /** Array of saved filters */\n readonly data: readonly SavedFilter[];\n}\n","import type { NotifyKitNotification, NotificationCategory, NotificationLevel } from '../types';\nimport { isModalSpec } from '../types/modal';\nimport {\n isNotifyKitNotification,\n isValidCategory,\n isValidLevel,\n} from '../types/notification';\n\ninterface RawApiNotification {\n readonly id: string;\n readonly type: string | undefined;\n readonly data: Record<string, unknown>;\n readonly read_at: string | null | undefined;\n readonly created_at: string | undefined;\n}\n\nconst RESERVED_PAYLOAD_KEYS = new Set<string>([\n 'id',\n 'key',\n 'category',\n 'level',\n 'title',\n 'body',\n 'action_url',\n 'workspace_id',\n 'modal',\n 'group_key',\n 'idempotency_key',\n 'read_at',\n 'created_at',\n 'data',\n]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction nullableString(value: unknown): string | null {\n return typeof value === 'string' && value.trim() !== '' ? value : null;\n}\n\nfunction stringOrFallback(value: unknown, fallback: string): string {\n return typeof value === 'string' && value.trim() !== '' ? value : fallback;\n}\n\nfunction inferCategory(key: string): NotificationCategory {\n if (key.startsWith('workspace.')) {\n return 'workspace';\n }\n if (key.startsWith('security.')) {\n return 'security';\n }\n if (key.startsWith('orders.')) {\n return 'orders';\n }\n if (key.startsWith('social.') || key.includes('mention') || key.includes('comment')) {\n return 'social';\n }\n if (key.startsWith('marketing.')) {\n return 'marketing';\n }\n\n return 'system';\n}\n\nfunction inferLevel(value: unknown): NotificationLevel {\n if (isValidLevel(value)) {\n return value;\n }\n\n return 'info';\n}\n\nfunction buildUser(payload: Record<string, unknown>): Record<string, unknown> | undefined {\n const actorId = nullableString(payload['actor_id']);\n if (actorId === null) {\n return undefined;\n }\n\n const user: Record<string, unknown> = {\n id: actorId,\n name: stringOrFallback(payload['actor_name'], 'Someone'),\n handle: nullableString(payload['actor_handle']) ?? '',\n };\n\n const avatar = nullableString(payload['actor_avatar']);\n if (avatar !== null) {\n user['avatar'] = avatar;\n }\n\n return user;\n}\n\nexport function normalizeApiNotification(raw: unknown): NotifyKitNotification {\n if (isNotifyKitNotification(raw)) {\n return raw;\n }\n\n const rawRecord: RawApiNotification = isRecord(raw)\n ? {\n id: stringOrFallback(raw['id'], ''),\n type: nullableString(raw['type']) ?? undefined,\n data: isRecord(raw['data']) ? raw['data'] : {},\n read_at: nullableString(raw['read_at']),\n created_at: nullableString(raw['created_at']) ?? undefined,\n }\n : {\n id: '',\n type: undefined,\n data: {},\n read_at: undefined,\n created_at: undefined,\n };\n const payload = isRecord(rawRecord.data) ? rawRecord.data : {};\n const nestedData = isRecord(payload['data']) ? payload['data'] : {};\n const key = stringOrFallback(payload['key'], stringOrFallback(rawRecord.type, 'system.notification'));\n const category = isValidCategory(payload['category'])\n ? payload['category']\n : inferCategory(key);\n const title = stringOrFallback(payload['title'], stringOrFallback(payload['message'], 'Notification'));\n const body = stringOrFallback(payload['body'], stringOrFallback(payload['message'], title));\n const actionUrl = nullableString(payload['action_url']) ?? nullableString(payload['link']);\n const user = buildUser(payload);\n\n const data: Record<string, unknown> = {\n ...nestedData,\n };\n\n for (const [entryKey, entryValue] of Object.entries(payload)) {\n if (entryKey === 'data' || RESERVED_PAYLOAD_KEYS.has(entryKey)) {\n continue;\n }\n\n data[entryKey] = entryValue;\n }\n\n if (typeof payload['key'] === 'string') {\n data['key'] = payload['key'];\n }\n if (typeof payload['title'] === 'string') {\n data['title'] = payload['title'];\n }\n\n data['body'] = body;\n data['message'] = body;\n\n if (actionUrl !== null) {\n data['action_url'] = actionUrl;\n data['link'] = actionUrl;\n }\n\n if (user !== undefined) {\n data['user'] = user;\n }\n\n return {\n id: stringOrFallback(rawRecord.id, ''),\n key,\n category,\n level: inferLevel(payload['level']),\n title,\n body,\n action_url: actionUrl,\n workspace_id: nullableString(payload['workspace_id']),\n modal: isModalSpec(payload['modal']) ? payload['modal'] : null,\n group_key: nullableString(payload['group_key']),\n idempotency_key: nullableString(payload['idempotency_key']),\n data,\n read_at: rawRecord.read_at ?? null,\n created_at: stringOrFallback(rawRecord.created_at, new Date().toISOString()),\n };\n}\n","/**\n * Notify Kit HTTP Client\n *\n * Provides type-safe access to all Notify Kit API endpoints.\n */\n\nimport type {\n NotifyKitNotification,\n NotifyKitMeResponse,\n NotifyKitListResponse,\n NotifyKitUnreadCountResponse,\n NotifyKitSingleNotificationResponse,\n NotifyKitReadMutationResponse,\n NotifyKitPreferenceSettingsQuery,\n NotifyKitPreferences,\n NotifyKitPreferencesUpdate,\n ListNotificationsParams,\n PaginationParams,\n BulkFilters,\n BulkActionResult,\n SearchFilters,\n SearchResult,\n SavedFilter,\n SavedFiltersResponse,\n} from '../types';\nimport { normalizeApiNotification } from './normalizeNotification';\n\n/**\n * Configuration options for the NotifyKit client.\n */\nexport interface NotifyKitClientConfig {\n /** Base URL for the Notify Kit API (e.g., '/api/notify-kit' or 'https://api.example.com') */\n baseUrl: string;\n\n /** Optional function to provide auth headers for requests */\n getAuthHeaders?: () => Record<string, string> | Promise<Record<string, string>>;\n\n /** Optional custom fetch implementation (defaults to global fetch) */\n fetch?: typeof fetch;\n}\n\n/**\n * API error thrown when requests fail.\n */\nexport class NotifyKitApiError extends Error {\n public override readonly name = 'NotifyKitApiError';\n\n constructor(\n message: string,\n public readonly status: number,\n public readonly errors?: Readonly<Record<string, readonly string[]>>,\n public readonly headers?: Readonly<Record<string, string>>\n ) {\n super(message);\n }\n}\n\n/**\n * HTTP Client for the Notify Kit API.\n */\nexport class NotifyKitClient {\n private readonly baseUrl: string;\n private readonly getAuthHeaders:\n | (() => Record<string, string> | Promise<Record<string, string>>)\n | undefined;\n private readonly fetchFn: typeof fetch;\n\n constructor(config: NotifyKitClientConfig) {\n // Strip trailing slash from baseUrl\n this.baseUrl = config.baseUrl.replace(/\\/+$/, '');\n this.getAuthHeaders = config.getAuthHeaders ?? undefined;\n this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n // ============================================\n // Me\n // ============================================\n\n /**\n * Get the current user's broadcast channel information.\n */\n async getMe(): Promise<NotifyKitMeResponse> {\n return this.request<NotifyKitMeResponse>('GET', '/me');\n }\n\n // ============================================\n // Notifications\n // ============================================\n\n /**\n * List notifications for the current user.\n */\n async listNotifications(\n params?: ListNotificationsParams\n ): Promise<NotifyKitListResponse> {\n const queryParams = this.buildNotificationParams(params);\n const queryString = queryParams.toString();\n const url = queryString.length > 0 ? `/notifications?${queryString}` : '/notifications';\n const response = await this.request<{\n data: readonly unknown[];\n meta: NotifyKitListResponse['meta'];\n }>('GET', url);\n\n return {\n data: response.data.map((notification) => normalizeApiNotification(notification)),\n meta: response.meta,\n };\n }\n\n /**\n * Get the count of unread notifications.\n */\n async getUnreadCount(): Promise<NotifyKitUnreadCountResponse> {\n return this.request<NotifyKitUnreadCountResponse>(\n 'GET',\n '/notifications/unread-count'\n );\n }\n\n /**\n * Get a single notification for the current user.\n */\n async getNotification(id: string): Promise<NotifyKitNotification> {\n const response = await this.request<NotifyKitSingleNotificationResponse>(\n 'GET',\n `/notifications/${id}`\n );\n return normalizeApiNotification(response.data);\n }\n\n /**\n * Mark a notification as read.\n */\n async markRead(id: string): Promise<NotifyKitReadMutationResponse> {\n return this.request<NotifyKitReadMutationResponse>('PATCH', `/notifications/${id}/read`);\n }\n\n /**\n * Mark all notifications as read.\n */\n async markAllRead(): Promise<void> {\n await this.request<undefined>('POST', '/notifications/read-all');\n }\n\n /**\n * Delete a notification.\n */\n async deleteNotification(id: string): Promise<void> {\n await this.request<undefined>('DELETE', `/notifications/${id}`);\n }\n\n // ============================================\n // Groups (Phase 2)\n // ============================================\n\n /**\n * Mark all notifications in a group as read.\n */\n async markGroupRead(groupKey: string): Promise<void> {\n await this.request<undefined>('PATCH', `/notifications/groups/${groupKey}/read`);\n }\n\n /**\n * Get all notifications in a group.\n */\n async getGroupNotifications(\n groupKey: string,\n params?: PaginationParams\n ): Promise<NotifyKitListResponse> {\n const queryParams = new URLSearchParams();\n if (params?.page !== undefined) {\n queryParams.set('page', String(params.page));\n }\n if (params?.per_page !== undefined) {\n queryParams.set('per_page', String(params.per_page));\n }\n const queryString = queryParams.toString();\n const url =\n queryString.length > 0\n ? `/notifications/groups/${groupKey}?${queryString}`\n : `/notifications/groups/${groupKey}`;\n const response = await this.request<{\n data: readonly unknown[];\n meta: NotifyKitListResponse['meta'];\n }>('GET', url);\n\n return {\n data: response.data.map((notification) => normalizeApiNotification(notification)),\n meta: response.meta,\n };\n }\n\n // ============================================\n // Modals\n // ============================================\n\n /**\n * List outstanding modal notifications.\n */\n async listModals(): Promise<readonly NotifyKitNotification[]> {\n const response = await this.request<{ data: NotifyKitNotification[] }>(\n 'GET',\n '/modals'\n );\n return response.data;\n }\n\n /**\n * Acknowledge a modal notification.\n */\n async ackModal(id: string): Promise<void> {\n await this.request<undefined>('POST', `/modals/${id}/ack`);\n }\n\n /**\n * Snooze a modal notification.\n */\n async snoozeModal(id: string, minutes: number): Promise<void> {\n await this.request<undefined>('POST', `/modals/${id}/snooze`, { minutes });\n }\n\n // ============================================\n // Preferences\n // ============================================\n\n /**\n * Get the current user's notification preference settings.\n */\n async getPreferenceSettings(\n query?: NotifyKitPreferenceSettingsQuery\n ): Promise<NotifyKitPreferences> {\n const queryParams = new URLSearchParams();\n\n if (query?.workspace_id !== undefined && query.workspace_id !== null) {\n queryParams.set('workspace_id', query.workspace_id);\n }\n\n const queryString = queryParams.toString();\n const url =\n queryString.length > 0\n ? `/preference-settings?${queryString}`\n : '/preference-settings';\n const response = await this.request<{ data: NotifyKitPreferences }>('GET', url);\n\n return response.data;\n }\n\n /**\n * Alias for getPreferenceSettings.\n */\n async getPreferences(\n query?: NotifyKitPreferenceSettingsQuery\n ): Promise<NotifyKitPreferences> {\n return this.getPreferenceSettings(query);\n }\n\n /**\n * Update the current user's notification preference settings.\n */\n async updatePreferenceSettings(\n preferences: NotifyKitPreferencesUpdate\n ): Promise<NotifyKitPreferences> {\n const response = await this.request<{ data: NotifyKitPreferences }>(\n 'PATCH',\n '/preference-settings',\n preferences\n );\n\n return response.data;\n }\n\n /**\n * Alias for updatePreferenceSettings.\n */\n async updatePreferences(\n preferences: NotifyKitPreferencesUpdate\n ): Promise<NotifyKitPreferences> {\n return this.updatePreferenceSettings(preferences);\n }\n\n // ============================================\n // Bulk Actions\n // ============================================\n\n /**\n * Bulk mark notifications as read.\n */\n async bulkMarkRead(ids: readonly string[]): Promise<BulkActionResult> {\n return this.request<BulkActionResult>('POST', '/notifications/bulk/read', {\n notification_ids: ids,\n });\n }\n\n /**\n * Bulk mark all matching notifications as read.\n */\n async bulkMarkAllRead(filters?: BulkFilters): Promise<BulkActionResult> {\n return this.request<BulkActionResult>('POST', '/notifications/bulk/read', {\n all: true,\n filters,\n });\n }\n\n /**\n * Bulk archive notifications.\n */\n async bulkArchive(ids: readonly string[]): Promise<BulkActionResult> {\n return this.request<BulkActionResult>('POST', '/notifications/bulk/archive', {\n notification_ids: ids,\n });\n }\n\n /**\n * Bulk archive all matching notifications.\n */\n async bulkArchiveAll(filters?: BulkFilters): Promise<BulkActionResult> {\n return this.request<BulkActionResult>('POST', '/notifications/bulk/archive', {\n all: true,\n filters,\n });\n }\n\n /**\n * Bulk delete notifications.\n */\n async bulkDelete(ids: readonly string[]): Promise<BulkActionResult> {\n return this.request<BulkActionResult>('POST', '/notifications/bulk/delete', {\n notification_ids: ids,\n });\n }\n\n /**\n * Bulk delete all matching notifications.\n */\n async bulkDeleteAll(filters?: BulkFilters): Promise<BulkActionResult> {\n return this.request<BulkActionResult>('POST', '/notifications/bulk/delete', {\n all: true,\n filters,\n });\n }\n\n // ============================================\n // Search\n // ============================================\n\n /**\n * Search notifications by query.\n */\n async search(query: string, filters?: SearchFilters, limit?: number): Promise<SearchResult> {\n const queryParams = new URLSearchParams();\n queryParams.set('q', query);\n\n if (filters?.category !== undefined) {\n queryParams.set('category', filters.category);\n }\n if (filters?.unread === true) {\n queryParams.set('unread', '1');\n }\n if (filters?.level !== undefined) {\n queryParams.set('level', filters.level);\n }\n if (limit !== undefined) {\n queryParams.set('limit', String(limit));\n }\n\n const response = await this.request<SearchResult>('GET', `/notifications/search?${queryParams.toString()}`);\n\n return {\n data: response.data.map((notification) => normalizeApiNotification(notification)),\n total: response.total,\n };\n }\n\n /**\n * Get saved filters (system + custom).\n */\n async getSavedFilters(): Promise<readonly SavedFilter[]> {\n const response = await this.request<SavedFiltersResponse>('GET', '/notifications/filters');\n return response.data;\n }\n\n /**\n * Save a custom filter.\n */\n async saveFilter(name: string, filters: Record<string, unknown>): Promise<SavedFilter> {\n const response = await this.request<{ data: SavedFilter }>('POST', '/notifications/filters', {\n name,\n filters,\n });\n return response.data;\n }\n\n /**\n * Delete a custom filter.\n */\n async deleteFilter(filterId: string): Promise<void> {\n await this.request<undefined>('DELETE', `/notifications/filters/${filterId}`);\n }\n\n // ============================================\n // Archive\n // ============================================\n\n /**\n * Archive a notification.\n */\n async archiveNotification(id: string): Promise<void> {\n await this.request<undefined>('POST', `/notifications/${id}/archive`);\n }\n\n /**\n * Unarchive a notification.\n */\n async unarchiveNotification(id: string): Promise<void> {\n await this.request<undefined>('POST', `/notifications/${id}/unarchive`);\n }\n\n // ============================================\n // Private helpers\n // ============================================\n\n private buildNotificationParams(params?: ListNotificationsParams): URLSearchParams {\n const queryParams = new URLSearchParams();\n\n if (params === undefined) {\n return queryParams;\n }\n\n if (params.unread === true) {\n queryParams.set('unread', 'true');\n }\n if (params.category !== undefined) {\n queryParams.set('category', params.category);\n }\n if (params.workspace_id !== undefined) {\n queryParams.set('workspace_id', params.workspace_id);\n }\n if (params.grouped === true) {\n queryParams.set('grouped', '1');\n }\n if (params.page !== undefined) {\n queryParams.set('page', String(params.page));\n }\n if (params.per_page !== undefined) {\n queryParams.set('per_page', String(params.per_page));\n }\n\n return queryParams;\n }\n\n private async request<T>(\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',\n path: string,\n body?: unknown\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n };\n\n // Add auth headers if provided\n if (this.getAuthHeaders !== undefined) {\n const authHeaders = await this.getAuthHeaders();\n Object.assign(headers, authHeaders);\n }\n\n const requestInit: RequestInit = {\n method,\n headers,\n };\n\n if (body !== undefined) {\n requestInit.body = JSON.stringify(body);\n }\n\n const response = await this.fetchFn(url, requestInit);\n\n if (!response.ok) {\n const responseHeaders = Object.fromEntries(\n Array.from(response.headers.entries()).map(([key, value]) => [key.toLowerCase(), value])\n );\n const errorData = (await response.json()) as {\n message?: string;\n errors?: Record<string, string[]>;\n };\n throw new NotifyKitApiError(\n errorData.message ?? `Request failed with status ${String(response.status)}`,\n response.status,\n errorData.errors,\n responseHeaders\n );\n }\n\n // Handle empty responses (204 No Content, etc.)\n const text = await response.text();\n if (text.length === 0) {\n return undefined as T;\n }\n\n return JSON.parse(text) as T;\n }\n}\n\n/**\n * Create a new NotifyKit client instance.\n */\nexport function createNotifyKitClient(config: NotifyKitClientConfig): NotifyKitClient {\n return new NotifyKitClient(config);\n}\n","/**\n * Notify Kit API endpoint constants.\n *\n * These are provided for reference and debugging purposes.\n * The NotifyKitClient class handles URL construction internally.\n */\n\nexport const ENDPOINTS = {\n /** GET - Returns broadcast channel for authenticated user */\n ME: '/me',\n\n /** GET - List notifications (supports filters and pagination) */\n NOTIFICATIONS: '/notifications',\n\n /** GET - Get count of unread notifications */\n UNREAD_COUNT: '/notifications/unread-count',\n\n /** PATCH - Mark a specific notification as read */\n MARK_READ: (id: string): string => `/notifications/${id}/read`,\n\n /** POST - Mark all notifications as read */\n MARK_ALL_READ: '/notifications/read-all',\n\n /** DELETE - Delete a specific notification */\n DELETE_NOTIFICATION: (id: string): string => `/notifications/${id}`,\n\n /** PATCH - Mark all notifications in a group as read (Phase 2) */\n MARK_GROUP_READ: (groupKey: string): string =>\n `/notifications/groups/${groupKey}/read`,\n\n /** GET - Get all notifications in a group (Phase 2) */\n GROUP_NOTIFICATIONS: (groupKey: string): string =>\n `/notifications/groups/${groupKey}`,\n\n /** GET - List outstanding modal notifications */\n MODALS: '/modals',\n\n /** POST - Acknowledge a modal notification */\n ACK_MODAL: (id: string): string => `/modals/${id}/ack`,\n\n /** POST - Snooze a modal notification */\n SNOOZE_MODAL: (id: string): string => `/modals/${id}/snooze`,\n\n /** GET/PATCH - Get or update user's notification preference settings */\n PREFERENCE_SETTINGS: '/preference-settings',\n PREFERENCES: '/preference-settings',\n} as const;\n","/**\n * useNotifyKitClient composable\n *\n * Provides access to the NotifyKit HTTP client within Vue components.\n * Supports both direct configuration and provide/inject pattern.\n */\n\nimport { inject, provide, type InjectionKey } from 'vue';\nimport {\n NotifyKitClient,\n createNotifyKitClient,\n type NotifyKitClientConfig,\n} from '../client';\nimport type {\n NotifyKitMeResponse,\n NotifyKitListResponse,\n NotifyKitUnreadCountResponse,\n NotifyKitReadMutationResponse,\n NotifyKitNotification,\n NotifyKitPreferenceSettingsQuery,\n NotifyKitPreferences,\n NotifyKitPreferencesUpdate,\n ListNotificationsParams,\n PaginationParams,\n} from '../types';\n\n/**\n * Injection key for the NotifyKit client.\n */\nexport const NOTIFY_KIT_CLIENT_KEY: InjectionKey<NotifyKitClient> = Symbol(\n 'notify-kit-client'\n);\n\n/**\n * Return type of useNotifyKitClient composable.\n */\nexport interface UseNotifyKitClientReturn {\n /** The underlying NotifyKitClient instance */\n readonly client: NotifyKitClient;\n\n // Me\n getMe: () => Promise<NotifyKitMeResponse>;\n\n // Notifications\n listNotifications: (params?: ListNotificationsParams) => Promise<NotifyKitListResponse>;\n getUnreadCount: () => Promise<NotifyKitUnreadCountResponse>;\n getNotification: (id: string) => Promise<NotifyKitNotification>;\n markRead: (id: string) => Promise<NotifyKitReadMutationResponse>;\n markAllRead: () => Promise<void>;\n deleteNotification: (id: string) => Promise<void>;\n\n // Groups\n markGroupRead: (groupKey: string) => Promise<void>;\n getGroupNotifications: (\n groupKey: string,\n params?: PaginationParams\n ) => Promise<NotifyKitListResponse>;\n\n // Modals\n listModals: () => Promise<readonly NotifyKitNotification[]>;\n ackModal: (id: string) => Promise<void>;\n snoozeModal: (id: string, minutes: number) => Promise<void>;\n\n // Preferences\n getPreferenceSettings: (\n query?: NotifyKitPreferenceSettingsQuery\n ) => Promise<NotifyKitPreferences>;\n updatePreferenceSettings: (\n preferences: NotifyKitPreferencesUpdate\n ) => Promise<NotifyKitPreferences>;\n getPreferences: (query?: NotifyKitPreferenceSettingsQuery) => Promise<NotifyKitPreferences>;\n updatePreferences: (\n preferences: NotifyKitPreferencesUpdate\n ) => Promise<NotifyKitPreferences>;\n}\n\n/**\n * Provides a NotifyKitClient for injection into descendant components.\n *\n * Call this in your app's setup or a parent component to make the client\n * available to all child components via useNotifyKitClient().\n *\n * @example\n * ```typescript\n * // In App.vue setup\n * provideNotifyKitClient({\n * baseUrl: '/api/notify-kit',\n * getAuthHeaders: () => ({ Authorization: `Bearer ${token}` })\n * })\n *\n * // In any child component\n * const { listNotifications, markRead } = useNotifyKitClient()\n * ```\n */\nexport function provideNotifyKitClient(config: NotifyKitClientConfig): NotifyKitClient {\n const client = createNotifyKitClient(config);\n provide(NOTIFY_KIT_CLIENT_KEY, client);\n return client;\n}\n\n/**\n * Access the NotifyKit client within a Vue component.\n *\n * If a config is provided, creates a new client instance.\n * Otherwise, uses the client provided via provideNotifyKitClient().\n *\n * @throws Error if no client is available (neither config nor injection)\n *\n * @example\n * ```typescript\n * // Use injected client\n * const { client, getMe, listNotifications } = useNotifyKitClient()\n *\n * // Or provide config directly\n * const { client } = useNotifyKitClient({\n * baseUrl: 'https://api.example.com/notify-kit'\n * })\n * ```\n */\nexport function useNotifyKitClient(config?: NotifyKitClientConfig): UseNotifyKitClientReturn {\n let client: NotifyKitClient;\n\n if (config !== undefined) {\n // Direct config provided - create new client\n client = createNotifyKitClient(config);\n } else {\n // Try to get from injection\n const injectedClient = inject(NOTIFY_KIT_CLIENT_KEY);\n if (injectedClient === undefined) {\n throw new Error(\n 'No NotifyKit client available. Either provide config to useNotifyKitClient() ' +\n 'or call provideNotifyKitClient() in a parent component.'\n );\n }\n client = injectedClient;\n }\n\n return {\n client,\n\n // Me\n getMe: (): Promise<NotifyKitMeResponse> => client.getMe(),\n\n // Notifications\n listNotifications: (params?: ListNotificationsParams): Promise<NotifyKitListResponse> =>\n client.listNotifications(params),\n getUnreadCount: (): Promise<NotifyKitUnreadCountResponse> => client.getUnreadCount(),\n getNotification: (id: string): Promise<NotifyKitNotification> => client.getNotification(id),\n markRead: (id: string): Promise<NotifyKitReadMutationResponse> => client.markRead(id),\n markAllRead: (): Promise<void> => client.markAllRead(),\n deleteNotification: (id: string): Promise<void> => client.deleteNotification(id),\n\n // Groups\n markGroupRead: (groupKey: string): Promise<void> => client.markGroupRead(groupKey),\n getGroupNotifications: (\n groupKey: string,\n params?: PaginationParams\n ): Promise<NotifyKitListResponse> => client.getGroupNotifications(groupKey, params),\n\n // Modals\n listModals: (): Promise<readonly NotifyKitNotification[]> => client.listModals(),\n ackModal: (id: string): Promise<void> => client.ackModal(id),\n snoozeModal: (id: string, minutes: number): Promise<void> =>\n client.snoozeModal(id, minutes),\n\n // Preferences\n getPreferenceSettings: (\n query?: NotifyKitPreferenceSettingsQuery\n ): Promise<NotifyKitPreferences> => client.getPreferenceSettings(query),\n updatePreferenceSettings: (\n preferences: NotifyKitPreferencesUpdate\n ): Promise<NotifyKitPreferences> => client.updatePreferenceSettings(preferences),\n getPreferences: (\n query?: NotifyKitPreferenceSettingsQuery\n ): Promise<NotifyKitPreferences> => client.getPreferences(query),\n updatePreferences: (\n preferences: NotifyKitPreferencesUpdate\n ): Promise<NotifyKitPreferences> => client.updatePreferences(preferences),\n };\n}\n","/**\n * useNotifyKitInbox composable\n *\n * Provides higher-level notification inbox orchestration on top of the\n * low-level Notify Kit store and HTTP client.\n */\n\nimport { computed, reactive, type ComputedRef } from 'vue';\nimport type {\n ListNotificationsParams,\n NotifyKitListResponse,\n NotifyKitNotification,\n NotifyKitReadMutationResponse,\n NotifyKitUnreadCountResponse,\n} from '../types';\nimport { useNotifyKitStore } from './useNotifyKitStore';\n\nconst DEFAULT_UNREAD_COUNT_RETRY_AFTER_MS = 30000;\nconst MIN_UNREAD_COUNT_RETRY_AFTER_MS = 5000;\nconst DEFAULT_UNREAD_COUNT_TRANSIENT_RETRY_MS = 10000;\nconst MAX_UNREAD_COUNT_TRANSIENT_RETRY_MS = 120000;\nconst MIN_UNREAD_COUNT_REFRESH_INTERVAL_MS = 5000;\nconst DEFAULT_PER_PAGE = 20;\n\nexport interface NotifyKitInboxClientLike {\n listNotifications: (params?: ListNotificationsParams) => Promise<NotifyKitListResponse>;\n getUnreadCount: () => Promise<NotifyKitUnreadCountResponse>;\n getNotification: (id: string) => Promise<NotifyKitNotification>;\n markRead: (id: string) => Promise<NotifyKitReadMutationResponse>;\n markAllRead: () => Promise<void>;\n deleteNotification: (id: string) => Promise<void>;\n}\n\nexport interface UseNotifyKitInboxOptions {\n client: NotifyKitInboxClientLike;\n perPage?: number;\n}\n\nexport interface UseNotifyKitInboxReturn {\n readonly notifications: ComputedRef<readonly NotifyKitNotification[]>;\n readonly unreadCount: ComputedRef<number>;\n readonly loading: ComputedRef<boolean>;\n readonly error: ComputedRef<string | null>;\n readonly hasMore: ComputedRef<boolean>;\n readonly nextPage: ComputedRef<number | null>;\n readonly isUnreadCountCoolingDown: ComputedRef<boolean>;\n\n loadUnreadCount: (force?: boolean) => Promise<boolean>;\n fetchNotifications: (\n page?: number | string | null,\n append?: boolean\n ) => Promise<readonly NotifyKitNotification[] | undefined>;\n loadMore: () => Promise<void>;\n markAsRead: (notificationId: string) => Promise<void>;\n markAllAsRead: () => Promise<void>;\n deleteNotification: (notificationId: string) => Promise<void>;\n clearAll: () => Promise<void>;\n reset: () => void;\n}\n\ninterface NotifyKitApiErrorLike {\n readonly status?: number | string;\n readonly headers?: Readonly<Record<string, string>>;\n}\n\ninterface InboxState {\n error: string | null;\n currentPage: number;\n lastPage: number;\n hasMore: boolean;\n unreadCountRetryAfterUntil: number;\n unreadCountLastLoadedAt: number;\n unreadCountTransientFailureCount: number;\n unreadCountRequest: Promise<boolean> | null;\n}\n\nfunction createInitialInboxState(): InboxState {\n return {\n error: null,\n currentPage: 0,\n lastPage: 1,\n hasMore: true,\n unreadCountRetryAfterUntil: 0,\n unreadCountLastLoadedAt: 0,\n unreadCountTransientFailureCount: 0,\n unreadCountRequest: null,\n };\n}\n\nlet inboxState: InboxState | null = null;\n\nfunction getInboxState(): InboxState {\n inboxState ??= reactive(createInitialInboxState()) as InboxState;\n return inboxState;\n}\n\nexport function resetNotifyKitInbox(): void {\n if (inboxState !== null) {\n Object.assign(inboxState, createInitialInboxState());\n }\n}\n\nfunction resolveStatusCode(statusCode: number | string | undefined): number | undefined {\n if (typeof statusCode === 'number' && Number.isFinite(statusCode)) {\n return statusCode;\n }\n\n if (typeof statusCode === 'string') {\n const parsedStatus = Number.parseInt(statusCode, 10);\n if (Number.isFinite(parsedStatus)) {\n return parsedStatus;\n }\n }\n\n return undefined;\n}\n\nfunction resolveRetryAfterMs(retryAfterHeader: unknown): number {\n if (\n typeof retryAfterHeader === 'number' &&\n Number.isFinite(retryAfterHeader) &&\n retryAfterHeader > 0\n ) {\n return Math.max(MIN_UNREAD_COUNT_RETRY_AFTER_MS, retryAfterHeader * 1000);\n }\n\n if (typeof retryAfterHeader === 'string') {\n const parsedSeconds = Number.parseInt(retryAfterHeader, 10);\n if (Number.isFinite(parsedSeconds) && parsedSeconds > 0) {\n return Math.max(MIN_UNREAD_COUNT_RETRY_AFTER_MS, parsedSeconds * 1000);\n }\n }\n\n return DEFAULT_UNREAD_COUNT_RETRY_AFTER_MS;\n}\n\nfunction isServerFailureStatus(statusCode: number | undefined): boolean {\n return typeof statusCode === 'number' && statusCode >= 500 && statusCode < 600;\n}\n\nfunction resolveTransientRetryMs(failureCount: number): number {\n const sanitizedFailureCount = Math.max(1, failureCount);\n const exponentialRetryMs =\n DEFAULT_UNREAD_COUNT_TRANSIENT_RETRY_MS * 2 ** (sanitizedFailureCount - 1);\n\n return Math.min(MAX_UNREAD_COUNT_TRANSIENT_RETRY_MS, exponentialRetryMs);\n}\n\nfunction resolveErrorMessage(error: unknown): string {\n if (error instanceof Error && error.message.length > 0) {\n return error.message;\n }\n\n if (typeof error === 'string' && error.length > 0) {\n return error;\n }\n\n return 'Request failed';\n}\n\nfunction asNotifyKitApiError(error: unknown): NotifyKitApiErrorLike | null {\n if (typeof error !== 'object' || error === null) {\n return null;\n }\n\n const status = 'status' in error ? error.status : undefined;\n const headers = 'headers' in error ? error.headers : undefined;\n const resolvedStatus =\n typeof status === 'number' || typeof status === 'string' ? status : undefined;\n const resolvedHeaders =\n typeof headers === 'object' && headers !== null\n ? (headers as Readonly<Record<string, string>>)\n : undefined;\n\n if (resolvedStatus === undefined && resolvedHeaders === undefined) {\n return {};\n }\n\n return {\n ...(resolvedStatus !== undefined ? { status: resolvedStatus } : {}),\n ...(resolvedHeaders !== undefined ? { headers: resolvedHeaders } : {}),\n };\n}\n\nexport function useNotifyKitInbox(options: UseNotifyKitInboxOptions): UseNotifyKitInboxReturn {\n const { client, perPage = DEFAULT_PER_PAGE } = options;\n\n const store = useNotifyKitStore();\n const state = getInboxState();\n\n const notifications = computed(() => store.state.notifications);\n const unreadCount = computed(() => store.state.unreadCount);\n const loading = computed(() => store.state.notificationsLoading);\n const error = computed(() => state.error);\n const hasMore = computed(() => state.hasMore);\n const nextPage = computed(() => (state.hasMore ? state.currentPage + 1 : null));\n const isUnreadCountCoolingDown = computed(\n () => Date.now() < state.unreadCountRetryAfterUntil\n );\n\n function reconcileUnreadCountForFullyLoadedList(): void {\n if (state.hasMore) {\n return;\n }\n\n const resolvedUnreadCount = store.state.notifications.filter(\n (notification) => notification.read_at === null\n ).length;\n store.setUnreadCount(resolvedUnreadCount);\n }\n\n async function loadUnreadCount(force = false): Promise<boolean> {\n if (!force && Date.now() < state.unreadCountRetryAfterUntil) {\n return false;\n }\n\n if (state.unreadCountRequest !== null) {\n return await state.unreadCountRequest;\n }\n\n const now = Date.now();\n if (!force && now - state.unreadCountLastLoadedAt < MIN_UNREAD_COUNT_REFRESH_INTERVAL_MS) {\n return true;\n }\n\n store.setUnreadCountLoading(true);\n state.unreadCountRequest = (async (): Promise<boolean> => {\n try {\n const response = await client.getUnreadCount();\n\n store.setUnreadCount(response.count);\n state.unreadCountLastLoadedAt = Date.now();\n state.unreadCountTransientFailureCount = 0;\n state.unreadCountRetryAfterUntil = 0;\n return true;\n } catch (error) {\n const apiError = asNotifyKitApiError(error);\n const statusCode = resolveStatusCode(apiError?.status);\n\n if (statusCode === 429) {\n const retryAfterHeader = apiError?.headers?.['retry-after'];\n state.unreadCountRetryAfterUntil = Date.now() + resolveRetryAfterMs(retryAfterHeader);\n return false;\n }\n\n if (statusCode === 404) {\n store.setUnreadCount(0);\n state.unreadCountLastLoadedAt = Date.now();\n state.unreadCountTransientFailureCount = 0;\n state.unreadCountRetryAfterUntil = 0;\n return true;\n }\n\n state.unreadCountTransientFailureCount += 1;\n if (statusCode === undefined || isServerFailureStatus(statusCode)) {\n state.unreadCountRetryAfterUntil =\n Date.now() + resolveTransientRetryMs(state.unreadCountTransientFailureCount);\n return false;\n }\n\n state.unreadCountRetryAfterUntil =\n Date.now() + DEFAULT_UNREAD_COUNT_TRANSIENT_RETRY_MS;\n return false;\n } finally {\n store.setUnreadCountLoading(false);\n }\n })();\n\n const wasSuccessful = await state.unreadCountRequest.finally(() => {\n state.unreadCountRequest = null;\n });\n\n return wasSuccessful;\n }\n\n async function fetchNotifications(\n page: number | string | null = null,\n append = false\n ): Promise<readonly NotifyKitNotification[] | undefined> {\n if (store.state.notificationsLoading) {\n return undefined;\n }\n\n store.setNotificationsLoading(true);\n state.error = null;\n\n try {\n const pageNumber = page !== null ? Number(page) : 1;\n const response = await client.listNotifications({\n per_page: perPage,\n page: pageNumber,\n });\n const items = [...response.data];\n\n if (append) {\n store.setNotifications([...store.state.notifications, ...items]);\n } else {\n store.setNotifications(items);\n }\n\n store.setNotificationsMeta(response.meta);\n store.setLastNotificationsSync(Date.now());\n state.currentPage = response.meta.current_page;\n state.lastPage = response.meta.last_page;\n state.hasMore = response.meta.current_page < response.meta.last_page;\n reconcileUnreadCountForFullyLoadedList();\n\n return items;\n } catch (error) {\n state.error = resolveErrorMessage(error);\n store.setNotificationsMeta(null);\n state.currentPage = 0;\n state.lastPage = 1;\n state.hasMore = false;\n\n if (!append) {\n store.setNotifications([]);\n store.setUnreadCount(0);\n }\n\n throw error;\n } finally {\n store.setNotificationsLoading(false);\n }\n }\n\n async function markAsRead(notificationId: string): Promise<void> {\n const notification = store.state.notifications.find((item) => item.id === notificationId);\n const wasUnread = notification?.read_at === null;\n const response = await client.markRead(notificationId);\n\n if (wasUnread) {\n store.markNotificationRead(notificationId);\n }\n\n if (typeof response.unread_count === 'number') {\n store.setUnreadCount(Math.max(0, response.unread_count));\n return;\n }\n\n if (wasUnread) {\n store.decrementUnreadCount();\n }\n }\n\n async function markAllAsRead(): Promise<void> {\n try {\n await client.markAllRead();\n const readTimestamp = new Date().toISOString();\n const nextNotifications = store.state.notifications.map((notification) =>\n notification.read_at === null\n ? {\n ...notification,\n read_at: readTimestamp,\n }\n : notification\n );\n\n store.setNotifications(nextNotifications);\n await loadUnreadCount(true);\n } catch (error) {\n state.error = resolveErrorMessage(error);\n throw error;\n }\n }\n\n async function deleteNotification(notificationId: string): Promise<void> {\n await client.deleteNotification(notificationId);\n\n const notification = store.state.notifications.find((item) => item.id === notificationId);\n const wasUnread = notification?.read_at === null;\n\n store.removeNotification(notificationId);\n if (wasUnread) {\n store.decrementUnreadCount();\n }\n }\n\n async function clearAll(): Promise<void> {\n try {\n await client.markAllRead();\n store.setNotifications([]);\n store.setUnreadCount(0);\n } catch (error) {\n state.error = resolveErrorMessage(error);\n throw error;\n }\n }\n\n async function loadMore(): Promise<void> {\n if (!state.hasMore || store.state.notificationsLoading) {\n return;\n }\n\n await fetchNotifications(state.currentPage + 1, true);\n }\n\n function reset(): void {\n store.reset();\n Object.assign(state, createInitialInboxState());\n }\n\n return {\n notifications,\n unreadCount,\n loading,\n error,\n hasMore,\n nextPage,\n isUnreadCountCoolingDown,\n loadUnreadCount,\n fetchNotifications,\n loadMore,\n markAsRead,\n markAllAsRead,\n deleteNotification,\n clearAll,\n reset,\n };\n}\n","/**\n * useNotifyKitRealtimeState composable\n *\n * Owns generic notification state updates for realtime payloads:\n * payload normalization, idempotent merge-by-id behavior, and unread count\n * reconciliation for realtime read/delete transitions.\n */\n\nimport { useNotifyKitStore } from './useNotifyKitStore';\nimport {\n isModalEnabled,\n isModalSpec,\n isValidCategory,\n isValidLevel,\n type NotifyKitModalSpec,\n type NotifyKitNotification,\n} from '../types';\n\nexport interface UseNotifyKitRealtimeStateReturn {\n applyIncomingPayload: (payload: unknown) => NotifyKitNotification | null;\n applyIncomingNotification: (notification: NotifyKitNotification) => void;\n handleNotificationRead: (notificationId: string) => void;\n handleNotificationDeleted: (notificationId: string) => void;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction normalizeNullableString(value: unknown): string | null | undefined {\n if (value === undefined || value === null) {\n return null;\n }\n\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction normalizeModalSpec(value: unknown): NotifyKitModalSpec | null | undefined {\n if (value === undefined || value === null) {\n return null;\n }\n\n return isModalSpec(value) ? value : undefined;\n}\n\nfunction normalizeRealtimeNotificationPayload(payload: unknown): NotifyKitNotification | null {\n if (!isRecord(payload)) {\n return null;\n }\n\n const id = payload['id'];\n const key = payload['key'];\n const category = payload['category'];\n const level = payload['level'];\n const title = payload['title'];\n const body = payload['body'];\n const createdAt = payload['created_at'];\n\n if (\n typeof id !== 'string' ||\n typeof key !== 'string' ||\n !isValidCategory(category) ||\n !isValidLevel(level) ||\n typeof title !== 'string' ||\n typeof body !== 'string' ||\n typeof createdAt !== 'string'\n ) {\n return null;\n }\n\n const data = payload['data'];\n if (data !== undefined && !isRecord(data)) {\n return null;\n }\n\n const actionUrl = normalizeNullableString(payload['action_url']);\n const workspaceId = normalizeNullableString(payload['workspace_id']);\n const groupKey = normalizeNullableString(payload['group_key']);\n const idempotencyKey = normalizeNullableString(payload['idempotency_key']);\n const readAt = normalizeNullableString(payload['read_at']);\n const modal = normalizeModalSpec(payload['modal']);\n\n if (\n actionUrl === undefined ||\n workspaceId === undefined ||\n groupKey === undefined ||\n idempotencyKey === undefined ||\n readAt === undefined ||\n modal === undefined\n ) {\n return null;\n }\n\n return {\n id,\n key,\n category,\n level,\n title,\n body,\n action_url: actionUrl,\n workspace_id: workspaceId,\n modal,\n group_key: groupKey,\n idempotency_key: idempotencyKey,\n data: data ?? {},\n read_at: readAt,\n created_at: createdAt,\n };\n}\n\nexport function useNotifyKitRealtimeState(): UseNotifyKitRealtimeStateReturn {\n const store = useNotifyKitStore();\n\n function applyIncomingNotification(notification: NotifyKitNotification): void {\n const existingIndex = store.state.notifications.findIndex((item) => item.id === notification.id);\n if (existingIndex === -1) {\n store.setNotifications([notification, ...store.state.notifications]);\n if (notification.read_at === null) {\n store.incrementUnreadCount();\n }\n } else {\n const existing = store.state.notifications[existingIndex];\n const wasRead = existing?.read_at !== null;\n const isNowRead = notification.read_at !== null;\n const nextNotifications = [...store.state.notifications];\n\n nextNotifications.splice(existingIndex, 1);\n nextNotifications.unshift(notification);\n store.setNotifications(nextNotifications);\n\n if (wasRead && !isNowRead) {\n store.incrementUnreadCount();\n } else if (!wasRead && isNowRead) {\n store.decrementUnreadCount();\n }\n }\n\n if (isModalEnabled(notification)) {\n store.enqueueModal(notification);\n }\n }\n\n function applyIncomingPayload(payload: unknown): NotifyKitNotification | null {\n const notification = normalizeRealtimeNotificationPayload(payload);\n if (notification === null) {\n return null;\n }\n\n applyIncomingNotification(notification);\n return notification;\n }\n\n function handleNotificationRead(notificationId: string): void {\n const notification = store.state.notifications.find((item) => item.id === notificationId);\n if (notification?.read_at === null) {\n store.markNotificationRead(notificationId);\n store.decrementUnreadCount();\n }\n }\n\n function handleNotificationDeleted(notificationId: string): void {\n const notification = store.state.notifications.find((item) => item.id === notificationId);\n const wasUnread = notification?.read_at === null;\n\n store.removeNotification(notificationId);\n if (wasUnread) {\n store.decrementUnreadCount();\n }\n }\n\n return {\n applyIncomingPayload,\n applyIncomingNotification,\n handleNotificationRead,\n handleNotificationDeleted,\n };\n}\n","/**\n * Toast Policy Helpers\n *\n * Provides utilities for apps to decide which notifications should\n * display as toasts vs only appear in the notification inbox, and\n * which should play sound alerts.\n */\n\nimport type { NotifyKitNotification, NotificationCategory, NotificationLevel } from '../types';\n\n/**\n * Interface for toast policy implementations.\n * Apps can implement this directly for full customization.\n */\nexport interface ToastPolicy {\n /**\n * Determines if a notification should display as a toast.\n * @param notification The notification to evaluate\n * @returns true if the notification should toast\n */\n shouldToast(notification: NotifyKitNotification): boolean;\n\n /**\n * Determines if a notification should play a sound alert.\n * @param notification The notification to evaluate\n * @returns true if the notification should play sound\n */\n shouldPlaySound(notification: NotifyKitNotification): boolean;\n}\n\n/**\n * Configuration options for creating a custom toast policy.\n */\nexport interface ToastPolicyConfig {\n /**\n * Per-category toast settings.\n * true = toast, false = don't toast\n * Categories not specified use defaults.\n */\n toastCategories?: Partial<Record<NotificationCategory, boolean>>;\n\n /**\n * Notification levels that should play sound.\n * Defaults to ['danger'].\n */\n soundLevels?: NotificationLevel[];\n\n /**\n * Categories that should always play sound regardless of level.\n * Defaults to ['security'].\n */\n soundCategories?: NotificationCategory[];\n\n /**\n * Custom shouldToast function.\n * If provided, takes precedence over toastCategories.\n */\n shouldToast?: (notification: NotifyKitNotification) => boolean;\n\n /**\n * Custom shouldPlaySound function.\n * If provided, takes precedence over soundLevels and soundCategories.\n */\n shouldPlaySound?: (notification: NotifyKitNotification) => boolean;\n}\n\n/**\n * Default category toast settings.\n * - social: false (high frequency, would be noisy)\n * - All others: true\n */\nconst DEFAULT_TOAST_CATEGORIES: Record<NotificationCategory, boolean> = {\n workspace: true,\n security: true,\n orders: true,\n social: false,\n system: true,\n marketing: true,\n};\n\n/**\n * Default levels that play sound.\n */\nconst DEFAULT_SOUND_LEVELS: NotificationLevel[] = ['danger'];\n\n/**\n * Default categories that always play sound.\n */\nconst DEFAULT_SOUND_CATEGORIES: NotificationCategory[] = ['security'];\n\n/**\n * Checks if a notification has a critical modal that requires acknowledgment.\n * Critical modals suppress toasts because the modal itself is the UX.\n */\nfunction isCriticalModal(notification: NotifyKitNotification): boolean {\n return (\n notification.modal !== null &&\n notification.modal.enabled &&\n notification.modal.requires_ack\n );\n}\n\n/**\n * Default implementation of shouldToast.\n */\nfunction defaultShouldToast(\n notification: NotifyKitNotification,\n categorySettings: Record<NotificationCategory, boolean>\n): boolean {\n // Critical modals: no toast (modal is the UX)\n if (isCriticalModal(notification)) {\n return false;\n }\n\n // Use category-specific settings\n return categorySettings[notification.category];\n}\n\n/**\n * Default implementation of shouldPlaySound.\n */\nfunction defaultShouldPlaySound(\n notification: NotifyKitNotification,\n soundLevels: NotificationLevel[],\n soundCategories: NotificationCategory[]\n): boolean {\n // Play sound if level matches\n if (soundLevels.includes(notification.level)) {\n return true;\n }\n\n // Play sound if category matches\n if (soundCategories.includes(notification.category)) {\n return true;\n }\n\n return false;\n}\n\n/**\n * The default toast policy.\n *\n * Rules:\n * - Critical modals (requires_ack): no toast (modal is the UX)\n * - Security: always toast\n * - Social: no toast by default (high frequency)\n * - All others: toast\n *\n * Sound rules:\n * - Danger level: play sound\n * - Security category: play sound\n * - All others: no sound\n */\nexport const defaultToastPolicy: ToastPolicy = {\n shouldToast(notification: NotifyKitNotification): boolean {\n return defaultShouldToast(notification, DEFAULT_TOAST_CATEGORIES);\n },\n\n shouldPlaySound(notification: NotifyKitNotification): boolean {\n return defaultShouldPlaySound(\n notification,\n DEFAULT_SOUND_LEVELS,\n DEFAULT_SOUND_CATEGORIES\n );\n },\n};\n\n/**\n * Creates a custom toast policy with the specified overrides.\n *\n * @param config Configuration options for the policy\n * @returns A ToastPolicy instance\n *\n * @example\n * ```typescript\n * // Enable toasts for social, disable for marketing\n * const policy = createToastPolicy({\n * toastCategories: {\n * social: true,\n * marketing: false,\n * },\n * });\n *\n * // Custom sound for warnings\n * const policy = createToastPolicy({\n * soundLevels: ['warning', 'danger'],\n * });\n *\n * // Fully custom logic\n * const policy = createToastPolicy({\n * shouldToast: (n) => n.level === 'danger',\n * shouldPlaySound: (n) => n.category === 'security',\n * });\n * ```\n */\nexport function createToastPolicy(config: ToastPolicyConfig): ToastPolicy {\n // Merge category settings with defaults\n const categorySettings: Record<NotificationCategory, boolean> = {\n ...DEFAULT_TOAST_CATEGORIES,\n ...config.toastCategories,\n };\n\n // Use provided arrays or defaults\n const soundLevels = config.soundLevels ?? DEFAULT_SOUND_LEVELS;\n const soundCategories = config.soundCategories ?? DEFAULT_SOUND_CATEGORIES;\n\n return {\n shouldToast(notification: NotifyKitNotification): boolean {\n // Custom function takes precedence\n if (config.shouldToast !== undefined) {\n return config.shouldToast(notification);\n }\n return defaultShouldToast(notification, categorySettings);\n },\n\n shouldPlaySound(notification: NotifyKitNotification): boolean {\n // Custom function takes precedence\n if (config.shouldPlaySound !== undefined) {\n return config.shouldPlaySound(notification);\n }\n return defaultShouldPlaySound(notification, soundLevels, soundCategories);\n },\n };\n}\n","/**\n * Helpers for resolving and binding the current user's Notify Kit\n * broadcast channel outside of a specific Vue composable.\n */\n\nexport interface NotifyKitBroadcastChannelClientLike {\n getMe: () => Promise<{ broadcast_channel: string }>;\n}\n\nexport interface NotifyKitBroadcastEchoChannelLike {\n notification: (callback: (notification: unknown) => void) => NotifyKitBroadcastEchoChannelLike;\n}\n\nexport interface NotifyKitBroadcastEchoLike {\n private: (channel: string) => NotifyKitBroadcastEchoChannelLike;\n leave: (channel: string) => void;\n}\n\nexport interface ResolveNotifyKitBroadcastChannelOptions {\n client: NotifyKitBroadcastChannelClientLike;\n channel?: string;\n}\n\nexport interface BindNotifyKitBroadcastChannelOptions {\n echo: NotifyKitBroadcastEchoLike;\n channel: string;\n onNotification: (notification: unknown) => void;\n}\n\nexport interface NotifyKitBroadcastChannelSubscription {\n readonly channel: string;\n unsubscribe: () => void;\n}\n\nexport async function resolveNotifyKitBroadcastChannel(\n options: ResolveNotifyKitBroadcastChannelOptions\n): Promise<string> {\n const { client, channel } = options;\n\n if (typeof channel === 'string' && channel.length > 0) {\n return channel;\n }\n\n const meResponse = await client.getMe();\n\n return meResponse.broadcast_channel;\n}\n\nexport function bindNotifyKitBroadcastChannel(\n options: BindNotifyKitBroadcastChannelOptions\n): NotifyKitBroadcastChannelSubscription {\n const { echo, channel, onNotification } = options;\n\n echo.private(channel).notification(onNotification);\n\n return {\n channel,\n unsubscribe: (): void => {\n echo.leave(channel);\n },\n };\n}\n","/**\n * useNotifyKitRealtime composable\n *\n * Provides real-time notification handling via Laravel Echo.\n * Manages WebSocket connection, subscribes to user's broadcast channel,\n * and updates the store when notifications are received.\n */\n\nimport { ref, computed, onMounted, onUnmounted, type Ref, type ComputedRef } from 'vue';\nimport { useNotifyKitStore, type ConnectionState } from './useNotifyKitStore';\nimport { useNotifyKitRealtimeState } from './useNotifyKitRealtimeState';\nimport {\n bindNotifyKitBroadcastChannel,\n resolveNotifyKitBroadcastChannel,\n} from '../helpers';\nimport { type NotifyKitNotification } from '../types';\n\n/**\n * Minimal Echo interface - just what we need for notifications.\n * This allows consumers to pass their own Echo instance.\n */\nexport interface EchoLike {\n private: (channel: string) => EchoChannelLike;\n leave: (channel: string) => void;\n}\n\n/**\n * Minimal Echo channel interface.\n */\nexport interface EchoChannelLike {\n notification: (callback: (notification: unknown) => void) => EchoChannelLike;\n stopListening: (event: string) => EchoChannelLike;\n}\n\n/**\n * Minimal NotifyKit client interface - just the methods we need.\n */\nexport interface NotifyKitClientLike {\n getMe: () => Promise<{ broadcast_channel: string }>;\n}\n\n/**\n * Configuration options for useNotifyKitRealtime.\n */\nexport interface UseNotifyKitRealtimeOptions {\n /**\n * Laravel Echo instance or a function that returns one.\n * Function form is useful for lazy initialization or SSR safety.\n */\n echo: EchoLike | (() => EchoLike);\n\n /**\n * NotifyKit client instance for fetching broadcast channel.\n */\n client: NotifyKitClientLike;\n\n /**\n * Whether to auto-connect when the composable is created.\n * Default: true\n */\n autoConnect?: boolean;\n\n /**\n * Callback called when a notification is received.\n * Called after store is updated.\n */\n onNotification?: (notification: NotifyKitNotification) => void;\n\n /**\n * Callback called when connection state changes.\n */\n onConnectionChange?: (state: ConnectionState) => void;\n}\n\n/**\n * Return type of useNotifyKitRealtime composable.\n */\nexport interface UseNotifyKitRealtimeReturn {\n /** Whether currently connected */\n readonly isConnected: ComputedRef<boolean>;\n\n /** Current connection state */\n readonly connectionState: Ref<ConnectionState>;\n\n /** Connect to real-time notifications */\n connect: () => Promise<void>;\n\n /** Disconnect from real-time notifications */\n disconnect: () => void;\n\n /** Disconnect and reconnect */\n reconnect: () => Promise<void>;\n}\n\n/**\n * Composable for real-time notification handling via Laravel Echo.\n *\n * @example\n * ```typescript\n * import Echo from 'laravel-echo'\n * import { useNotifyKitRealtime } from '@coding-factory/notify-kit-client'\n *\n * const echo = new Echo({ ... })\n * const client = useNotifyKitClient()\n *\n * const {\n * isConnected,\n * connectionState,\n * connect,\n * disconnect\n * } = useNotifyKitRealtime({\n * echo,\n * client: client.client,\n * onNotification: (notification) => {\n * console.log('New notification:', notification.title)\n * }\n * })\n * ```\n */\nexport function useNotifyKitRealtime(options: UseNotifyKitRealtimeOptions): UseNotifyKitRealtimeReturn {\n const {\n echo: echoOption,\n client,\n autoConnect = true,\n onNotification,\n onConnectionChange,\n } = options;\n\n // Get the store for state management\n const store = useNotifyKitStore();\n const realtimeState = useNotifyKitRealtimeState();\n\n // Local state\n const connectionState = ref<ConnectionState>('disconnected');\n const currentChannel = ref<string | null>(null);\n const isSubscribed = ref(false);\n\n // Computed\n const isConnected = computed(() => connectionState.value === 'connected');\n\n /**\n * Get the Echo instance (handles function form).\n */\n function getEcho(): EchoLike {\n return typeof echoOption === 'function' ? echoOption() : echoOption;\n }\n\n /**\n * Update connection state and notify callback.\n */\n function setConnectionState(state: ConnectionState): void {\n connectionState.value = state;\n store.setConnectionState(state);\n onConnectionChange?.(state);\n }\n\n /**\n * Handle incoming notification from Echo.\n */\n function handleNotification(payload: unknown): void {\n const notification = realtimeState.applyIncomingPayload(payload);\n if (notification === null) {\n return;\n }\n\n onNotification?.(notification);\n }\n\n /**\n * Connect to real-time notifications.\n */\n async function connect(): Promise<void> {\n // Already connected or connecting\n if (connectionState.value === 'connected' || connectionState.value === 'connecting') {\n return;\n }\n\n setConnectionState('connecting');\n\n try {\n const channel = await resolveNotifyKitBroadcastChannel({ client });\n\n // Store the channel\n currentChannel.value = channel;\n store.setBroadcastChannel(channel);\n\n // Get Echo instance and subscribe\n const echo = getEcho();\n bindNotifyKitBroadcastChannel({\n echo,\n channel,\n onNotification: handleNotification,\n });\n isSubscribed.value = true;\n\n setConnectionState('connected');\n } catch (error) {\n setConnectionState('error');\n throw error;\n }\n }\n\n /**\n * Disconnect from real-time notifications.\n */\n function disconnect(): void {\n if (currentChannel.value !== null && isSubscribed.value) {\n const echo = getEcho();\n echo.leave(currentChannel.value);\n isSubscribed.value = false;\n }\n\n setConnectionState('disconnected');\n }\n\n /**\n * Disconnect and reconnect.\n */\n async function reconnect(): Promise<void> {\n disconnect();\n await connect();\n }\n\n // Lifecycle: auto-connect on mount if enabled\n onMounted(() => {\n if (autoConnect) {\n // Use void to explicitly ignore the promise\n void connect();\n }\n });\n\n // Lifecycle: cleanup on unmount\n onUnmounted(() => {\n if (isConnected.value) {\n disconnect();\n }\n });\n\n return {\n isConnected,\n connectionState,\n connect,\n disconnect,\n reconnect,\n };\n}\n","/**\n * useNotifyKitFallback composable\n *\n * Provides fallback polling when WebSocket connection fails.\n * Automatically starts polling when disconnected and stops when reconnected.\n */\n\nimport { ref, watch, onUnmounted, type Ref } from 'vue';\nimport { useNotifyKitStore, type ConnectionState } from './useNotifyKitStore';\nimport type { NotifyKitNotification } from '../types';\nimport type { NotifyKitClient } from '../client/NotifyKitClient';\n\nexport interface FallbackConfig {\n disconnectThresholdMs: number;\n unreadCountIntervalMs: number;\n modalsIntervalMs: number;\n reconnectGracePeriodMs: number;\n}\n\nconst DEFAULT_CONFIG: FallbackConfig = {\n disconnectThresholdMs: 5000,\n unreadCountIntervalMs: 30000,\n modalsIntervalMs: 120000,\n reconnectGracePeriodMs: 2000,\n};\n\nexport interface UseNotifyKitFallbackOptions {\n client: NotifyKitClient;\n connectionState: Ref<ConnectionState>;\n config?: Partial<FallbackConfig>;\n onModalsReceived?: (modals: readonly NotifyKitNotification[]) => void;\n onUnreadCountReceived?: (count: number) => void;\n}\n\nexport interface UseNotifyKitFallbackReturn {\n readonly isPolling: Ref<boolean>;\n readonly lastPollAt: Ref<number | null>;\n startPolling: () => void;\n stopPolling: () => void;\n pollUnreadCount: () => Promise<void>;\n pollModals: () => Promise<void>;\n}\n\nexport function useNotifyKitFallback(\n options: UseNotifyKitFallbackOptions\n): UseNotifyKitFallbackReturn {\n const { client, connectionState, config: userConfig, onModalsReceived, onUnreadCountReceived } =\n options;\n\n const config: FallbackConfig = {\n ...DEFAULT_CONFIG,\n ...userConfig,\n };\n\n const store = useNotifyKitStore();\n const isPolling = ref(false);\n const lastPollAt = ref<number | null>(null);\n\n let disconnectTimer: ReturnType<typeof setTimeout> | null = null;\n let unreadCountInterval: ReturnType<typeof setInterval> | null = null;\n let modalsInterval: ReturnType<typeof setInterval> | null = null;\n let reconnectGraceTimer: ReturnType<typeof setTimeout> | null = null;\n\n async function pollUnreadCount(): Promise<void> {\n try {\n const response = await client.getUnreadCount();\n store.setUnreadCount(response.count);\n lastPollAt.value = Date.now();\n onUnreadCountReceived?.(response.count);\n } catch {\n // Ignore polling errors and rely on the next poll window.\n }\n }\n\n async function pollModals(): Promise<void> {\n try {\n const modals = await client.listModals();\n for (const modal of modals) {\n store.enqueueModal(modal);\n }\n store.setLastModalsSync(Date.now());\n lastPollAt.value = Date.now();\n onModalsReceived?.(modals);\n } catch {\n // Ignore polling errors and rely on the next poll window.\n }\n }\n\n function startPolling(): void {\n if (isPolling.value) {\n return;\n }\n\n isPolling.value = true;\n void pollUnreadCount();\n void pollModals();\n\n unreadCountInterval = setInterval(() => {\n void pollUnreadCount();\n }, config.unreadCountIntervalMs);\n\n modalsInterval = setInterval(() => {\n void pollModals();\n }, config.modalsIntervalMs);\n }\n\n function stopPolling(): void {\n if (!isPolling.value) {\n return;\n }\n\n isPolling.value = false;\n\n if (unreadCountInterval !== null) {\n clearInterval(unreadCountInterval);\n unreadCountInterval = null;\n }\n\n if (modalsInterval !== null) {\n clearInterval(modalsInterval);\n modalsInterval = null;\n }\n }\n\n function clearAllTimers(): void {\n if (disconnectTimer !== null) {\n clearTimeout(disconnectTimer);\n disconnectTimer = null;\n }\n\n if (reconnectGraceTimer !== null) {\n clearTimeout(reconnectGraceTimer);\n reconnectGraceTimer = null;\n }\n }\n\n function handleConnectionStateChange(state: ConnectionState): void {\n if (state === 'disconnected' || state === 'error') {\n if (reconnectGraceTimer !== null) {\n clearTimeout(reconnectGraceTimer);\n reconnectGraceTimer = null;\n }\n\n disconnectTimer ??= setTimeout(() => {\n startPolling();\n disconnectTimer = null;\n }, config.disconnectThresholdMs);\n return;\n }\n\n if (state === 'connected') {\n if (disconnectTimer !== null) {\n clearTimeout(disconnectTimer);\n disconnectTimer = null;\n }\n\n if (isPolling.value) {\n reconnectGraceTimer = setTimeout(() => {\n stopPolling();\n void pollUnreadCount();\n void pollModals();\n reconnectGraceTimer = null;\n }, config.reconnectGracePeriodMs);\n }\n }\n }\n\n watch(connectionState, handleConnectionStateChange, { immediate: true });\n\n onUnmounted(() => {\n clearAllTimers();\n stopPolling();\n });\n\n return {\n isPolling,\n lastPollAt,\n startPolling,\n stopPolling,\n pollUnreadCount,\n pollModals,\n };\n}\n","/**\n * useNotifyKitBulkActions composable\n *\n * Provides state and methods for bulk notification operations.\n */\n\nimport { reactive, readonly, computed, type ComputedRef } from 'vue';\nimport type { BulkFilters, BulkActionResult } from '../types';\nimport type { NotifyKitClient } from '../client/NotifyKitClient';\nimport { useNotifyKitStore } from './useNotifyKitStore';\n\nexport interface BulkActionsState {\n readonly selectedIds: ReadonlySet<string>;\n readonly isSelectionMode: boolean;\n readonly isProcessing: boolean;\n readonly error: string | null;\n}\n\ninterface MutableBulkActionsState {\n selectedIds: Set<string>;\n isSelectionMode: boolean;\n isProcessing: boolean;\n error: string | null;\n}\n\nexport interface UseNotifyKitBulkActionsOptions {\n readonly client: NotifyKitClient;\n}\n\nexport interface UseNotifyKitBulkActionsReturn {\n readonly state: BulkActionsState;\n readonly selectedCount: ComputedRef<number>;\n readonly hasSelection: ComputedRef<boolean>;\n readonly selectedIdsArray: ComputedRef<readonly string[]>;\n toggleSelection: (id: string) => void;\n select: (id: string) => void;\n deselect: (id: string) => void;\n selectAll: (ids: readonly string[]) => void;\n clearSelection: () => void;\n enterSelectionMode: () => void;\n exitSelectionMode: () => void;\n markSelectedRead: () => Promise<BulkActionResult>;\n markAllRead: (filters?: BulkFilters) => Promise<BulkActionResult>;\n archiveSelected: () => Promise<BulkActionResult>;\n archiveAll: (filters?: BulkFilters) => Promise<BulkActionResult>;\n deleteSelected: () => Promise<BulkActionResult>;\n deleteAll: (filters?: BulkFilters) => Promise<BulkActionResult>;\n reset: () => void;\n}\n\nfunction createInitialState(): MutableBulkActionsState {\n return {\n selectedIds: new Set<string>(),\n isSelectionMode: false,\n isProcessing: false,\n error: null,\n };\n}\n\nexport function useNotifyKitBulkActions(\n options: UseNotifyKitBulkActionsOptions\n): UseNotifyKitBulkActionsReturn {\n const { client } = options;\n const store = useNotifyKitStore();\n const state = reactive(createInitialState());\n\n const selectedCount = computed(() => state.selectedIds.size);\n const hasSelection = computed(() => state.selectedIds.size > 0);\n const selectedIdsArray = computed(() => Array.from(state.selectedIds));\n\n function toggleSelection(id: string): void {\n if (state.selectedIds.has(id)) {\n state.selectedIds.delete(id);\n } else {\n state.selectedIds.add(id);\n }\n }\n\n function select(id: string): void {\n state.selectedIds.add(id);\n }\n\n function deselect(id: string): void {\n state.selectedIds.delete(id);\n }\n\n function selectAll(ids: readonly string[]): void {\n for (const id of ids) {\n state.selectedIds.add(id);\n }\n }\n\n function clearSelection(): void {\n state.selectedIds.clear();\n }\n\n function enterSelectionMode(): void {\n state.isSelectionMode = true;\n }\n\n function exitSelectionMode(): void {\n state.isSelectionMode = false;\n state.selectedIds.clear();\n }\n\n async function markSelectedRead(): Promise<BulkActionResult> {\n if (state.selectedIds.size === 0) {\n return { affected: 0, failed: 0 };\n }\n\n state.isProcessing = true;\n state.error = null;\n\n try {\n const ids = Array.from(state.selectedIds);\n const result = await client.bulkMarkRead(ids);\n\n for (const id of ids) {\n store.markNotificationRead(id);\n }\n\n if (result.affected > 0) {\n store.setUnreadCount(Math.max(0, store.state.unreadCount - result.affected));\n }\n\n clearSelection();\n return result;\n } catch (error) {\n state.error = error instanceof Error ? error.message : 'Failed to mark as read';\n throw error;\n } finally {\n state.isProcessing = false;\n }\n }\n\n async function markAllRead(filters?: BulkFilters): Promise<BulkActionResult> {\n state.isProcessing = true;\n state.error = null;\n\n try {\n const result = await client.bulkMarkAllRead(filters);\n if (filters === undefined) {\n store.setUnreadCount(0);\n }\n clearSelection();\n return result;\n } catch (error) {\n state.error = error instanceof Error ? error.message : 'Failed to mark all as read';\n throw error;\n } finally {\n state.isProcessing = false;\n }\n }\n\n async function archiveSelected(): Promise<BulkActionResult> {\n if (state.selectedIds.size === 0) {\n return { affected: 0, failed: 0 };\n }\n\n state.isProcessing = true;\n state.error = null;\n\n try {\n const ids = Array.from(state.selectedIds);\n const result = await client.bulkArchive(ids);\n\n for (const id of ids) {\n store.removeNotification(id);\n }\n\n clearSelection();\n return result;\n } catch (error) {\n state.error = error instanceof Error ? error.message : 'Failed to archive';\n throw error;\n } finally {\n state.isProcessing = false;\n }\n }\n\n async function archiveAll(filters?: BulkFilters): Promise<BulkActionResult> {\n state.isProcessing = true;\n state.error = null;\n\n try {\n const result = await client.bulkArchiveAll(filters);\n clearSelection();\n return result;\n } catch (error) {\n state.error = error instanceof Error ? error.message : 'Failed to archive all';\n throw error;\n } finally {\n state.isProcessing = false;\n }\n }\n\n async function deleteSelected(): Promise<BulkActionResult> {\n if (state.selectedIds.size === 0) {\n return { affected: 0, failed: 0 };\n }\n\n state.isProcessing = true;\n state.error = null;\n\n try {\n const ids = Array.from(state.selectedIds);\n const result = await client.bulkDelete(ids);\n\n for (const id of ids) {\n store.removeNotification(id);\n }\n\n clearSelection();\n return result;\n } catch (error) {\n state.error = error instanceof Error ? error.message : 'Failed to delete';\n throw error;\n } finally {\n state.isProcessing = false;\n }\n }\n\n async function deleteAll(filters?: BulkFilters): Promise<BulkActionResult> {\n state.isProcessing = true;\n state.error = null;\n\n try {\n const result = await client.bulkDeleteAll(filters);\n clearSelection();\n return result;\n } catch (error) {\n state.error = error instanceof Error ? error.message : 'Failed to delete all';\n throw error;\n } finally {\n state.isProcessing = false;\n }\n }\n\n function reset(): void {\n Object.assign(state, createInitialState());\n }\n\n return {\n state: readonly(state) as BulkActionsState,\n selectedCount,\n hasSelection,\n selectedIdsArray,\n toggleSelection,\n select,\n deselect,\n selectAll,\n clearSelection,\n enterSelectionMode,\n exitSelectionMode,\n markSelectedRead,\n markAllRead,\n archiveSelected,\n archiveAll,\n deleteSelected,\n deleteAll,\n reset,\n };\n}\n","/**\n * useNotifyKitSearch composable\n *\n * Provides state and methods for notification search functionality.\n */\n\nimport { reactive, readonly, computed, ref, type ComputedRef, type Ref } from 'vue';\nimport type { NotifyKitNotification, SearchFilters, SavedFilter } from '../types';\nimport type { NotifyKitClient } from '../client/NotifyKitClient';\n\nexport interface SearchState {\n readonly query: string;\n readonly results: readonly NotifyKitNotification[];\n readonly total: number;\n readonly isSearching: boolean;\n readonly hasSearched: boolean;\n readonly filters: SearchFilters | null;\n readonly error: string | null;\n}\n\ninterface MutableSearchState {\n query: string;\n results: NotifyKitNotification[];\n total: number;\n isSearching: boolean;\n hasSearched: boolean;\n filters: SearchFilters | null;\n error: string | null;\n}\n\nexport interface UseNotifyKitSearchOptions {\n readonly client: NotifyKitClient;\n readonly minQueryLength?: number;\n readonly debounceMs?: number;\n}\n\nexport interface UseNotifyKitSearchReturn {\n readonly state: SearchState;\n readonly hasResults: ComputedRef<boolean>;\n readonly resultCount: ComputedRef<number>;\n readonly isValidQuery: ComputedRef<boolean>;\n readonly savedFilters: Ref<readonly SavedFilter[]>;\n readonly savedFiltersLoading: Ref<boolean>;\n search: (query: string, filters?: SearchFilters) => Promise<void>;\n clearSearch: () => void;\n setFilters: (filters: SearchFilters | null) => void;\n loadSavedFilters: () => Promise<void>;\n applyFilter: (filter: SavedFilter) => Promise<void>;\n saveFilter: (name: string, filters: Record<string, unknown>) => Promise<SavedFilter>;\n deleteFilter: (filterId: string) => Promise<void>;\n reset: () => void;\n}\n\nfunction createInitialState(): MutableSearchState {\n return {\n query: '',\n results: [],\n total: 0,\n isSearching: false,\n hasSearched: false,\n filters: null,\n error: null,\n };\n}\n\nexport function useNotifyKitSearch(options: UseNotifyKitSearchOptions): UseNotifyKitSearchReturn {\n const { client, minQueryLength = 3 } = options;\n const state = reactive(createInitialState());\n const savedFilters = ref<readonly SavedFilter[]>([]);\n const savedFiltersLoading = ref(false);\n\n const hasResults = computed(() => state.results.length > 0);\n const resultCount = computed(() => state.results.length);\n const isValidQuery = computed(() => state.query.length >= minQueryLength);\n\n async function search(query: string, filters?: SearchFilters): Promise<void> {\n state.query = query;\n\n if (query.length < minQueryLength) {\n state.error = `Search query must be at least ${String(minQueryLength)} characters`;\n return;\n }\n\n state.isSearching = true;\n state.error = null;\n\n try {\n const effectiveFilters = filters ?? state.filters ?? undefined;\n const result = await client.search(query, effectiveFilters);\n\n state.results = [...result.data];\n state.total = result.total;\n state.hasSearched = true;\n\n if (filters !== undefined) {\n state.filters = filters;\n }\n } catch (error) {\n state.error = error instanceof Error ? error.message : 'Search failed';\n state.results = [];\n state.total = 0;\n } finally {\n state.isSearching = false;\n }\n }\n\n function clearSearch(): void {\n state.query = '';\n state.results = [];\n state.total = 0;\n state.hasSearched = false;\n state.error = null;\n }\n\n function setFilters(filters: SearchFilters | null): void {\n state.filters = filters;\n }\n\n async function loadSavedFilters(): Promise<void> {\n savedFiltersLoading.value = true;\n\n try {\n savedFilters.value = await client.getSavedFilters();\n } catch {\n // Keep existing filters if loading fails.\n } finally {\n savedFiltersLoading.value = false;\n }\n }\n\n async function applyFilter(filter: SavedFilter): Promise<void> {\n const searchFilters: SearchFilters = {};\n const categoryValue = filter.filters['category'];\n const levelValue = filter.filters['level'];\n\n if (typeof categoryValue === 'string') {\n (searchFilters as { category?: string }).category = categoryValue;\n }\n\n if (filter.filters['unread_only'] === true) {\n (searchFilters as { unread?: boolean }).unread = true;\n }\n\n if (typeof levelValue === 'string') {\n (searchFilters as { level?: string }).level = levelValue;\n }\n\n state.filters = searchFilters;\n\n if (state.query.length >= minQueryLength) {\n await search(state.query, searchFilters);\n }\n }\n\n async function saveFilter(name: string, filters: Record<string, unknown>): Promise<SavedFilter> {\n const createdFilter = await client.saveFilter(name, filters);\n savedFilters.value = [...savedFilters.value, createdFilter];\n return createdFilter;\n }\n\n async function deleteFilter(filterId: string): Promise<void> {\n await client.deleteFilter(filterId);\n savedFilters.value = savedFilters.value.filter((filter) => filter.id !== filterId);\n }\n\n function reset(): void {\n Object.assign(state, createInitialState());\n savedFilters.value = [];\n }\n\n return {\n state: readonly(state) as SearchState,\n hasResults,\n resultCount,\n isValidQuery,\n savedFilters,\n savedFiltersLoading,\n search,\n clearSearch,\n setFilters,\n loadSavedFilters,\n applyFilter,\n saveFilter,\n deleteFilter,\n reset,\n };\n}\n","/**\n * @coding-factory/notify-kit-client\n *\n * Headless Vue 3/Nuxt client for Notify Kit notifications.\n * Provides TypeScript types, HTTP client, composables, and Nuxt integration.\n */\n\n// Version export for debugging\nexport const VERSION = '0.2.2';\n\n// Types - matching backend payload contract exactly\nexport * from './types';\n\n// HTTP Client\nexport * from './client';\n\n// Vue 3 Composables\nexport * from './composables';\n\n// Helpers\nexport * from './helpers';\n"]}
1
+ {"version":3,"sources":["../src/types/modal.ts","../src/types/notification.ts","../src/types/preferences.ts","../src/types/api.ts","../src/client/normalizeNotification.ts","../src/client/NotifyKitClient.ts","../src/client/endpoints.ts","../src/composables/useNotifyKitClient.ts","../src/composables/useNotifyKitInbox.ts","../src/composables/useNotifyKitRealtimeState.ts","../src/helpers/toastPolicy.ts","../src/helpers/notifyKitRealtimeChannel.ts","../src/composables/useNotifyKitRealtime.ts","../src/composables/useNotifyKitFallback.ts","../src/composables/useNotifyKitBulkActions.ts","../src/composables/useNotifyKitSearch.ts","../src/index.ts"],"names":["error","isRecord","computed","ref","onUnmounted","reactive","createInitialState","readonly"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Modal-related type definitions for critical notification modals.\n */\n\n/**\n * Modal specification included in notifications that require modal display.\n */\nexport interface NotifyKitModalSpec {\n /** Whether modal display is enabled for this notification */\n readonly enabled: boolean;\n\n /** Whether the user must acknowledge before dismissing */\n readonly requires_ack: boolean;\n\n /** Available snooze duration options in minutes */\n readonly snooze_options_minutes: readonly number[];\n}\n\n/**\n * Modal state tracking for a notification.\n * This represents the user's interaction state with a modal notification.\n */\nexport interface NotifyKitModalState {\n /** Timestamp when the modal was acknowledged (ISO 8601), null if not yet acknowledged */\n readonly acknowledged_at: string | null;\n\n /** Timestamp until which the modal is snoozed (ISO 8601), null if not snoozed */\n readonly snoozed_until: string | null;\n}\n\n/**\n * Type guard to validate if a value is a valid NotifyKitModalSpec.\n */\nexport function isModalSpec(value: unknown): value is NotifyKitModalSpec {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const obj = value as Record<string, unknown>;\n\n if (typeof obj['enabled'] !== 'boolean') return false;\n if (typeof obj['requires_ack'] !== 'boolean') return false;\n if (!Array.isArray(obj['snooze_options_minutes'])) return false;\n\n // Validate all snooze options are positive integers\n const snoozeOptions = obj['snooze_options_minutes'] as unknown[];\n for (const option of snoozeOptions) {\n if (typeof option !== 'number' || !Number.isInteger(option) || option < 1) {\n return false;\n }\n }\n\n return true;\n}\n","/**\n * Notification type definitions matching the Notify Kit backend contract.\n */\n\nimport type { NotifyKitModalSpec } from './modal';\nimport { isModalSpec } from './modal';\n\n/**\n * Valid notification categories.\n */\nexport type NotificationCategory =\n | 'workspace'\n | 'security'\n | 'orders'\n | 'social'\n | 'system'\n | 'marketing';\n\n/**\n * Valid notification severity levels.\n */\nexport type NotificationLevel = 'info' | 'success' | 'warning' | 'danger';\n\n/**\n * All valid category values for runtime validation.\n */\nexport const NOTIFICATION_CATEGORIES: readonly NotificationCategory[] = [\n 'workspace',\n 'security',\n 'orders',\n 'social',\n 'system',\n 'marketing',\n] as const;\n\n/**\n * All valid level values for runtime validation.\n */\nexport const NOTIFICATION_LEVELS: readonly NotificationLevel[] = [\n 'info',\n 'success',\n 'warning',\n 'danger',\n] as const;\n\n/**\n * Core notification payload structure matching the Notify Kit backend contract.\n */\nexport interface NotifyKitNotification {\n /** Unique notification ID (UUID) */\n readonly id: string;\n\n /** Notification key (e.g., 'orders.shipped', 'security.critical_alert') */\n readonly key: string;\n\n /** Notification category */\n readonly category: NotificationCategory;\n\n /** Severity level */\n readonly level: NotificationLevel;\n\n /** Notification title */\n readonly title: string;\n\n /** Notification body text */\n readonly body: string;\n\n /** Optional URL for the notification action */\n readonly action_url: string | null;\n\n /** Workspace ID if this is a workspace-scoped notification */\n readonly workspace_id: string | null;\n\n /** Modal specification if this notification requires modal display */\n readonly modal: NotifyKitModalSpec | null;\n\n /** Group key for notification aggregation (Phase 2) */\n readonly group_key: string | null;\n\n /** Idempotency key to prevent duplicate notifications (Phase 2) */\n readonly idempotency_key: string | null;\n\n /** Additional arbitrary data */\n readonly data: Record<string, unknown>;\n\n /** Timestamp when notification was marked as read (ISO 8601) */\n readonly read_at: string | null;\n\n /** Timestamp when notification was created (ISO 8601) */\n readonly created_at: string;\n}\n\n/**\n * Type guard to validate if a value is a valid NotificationCategory.\n */\nexport function isValidCategory(value: unknown): value is NotificationCategory {\n return (\n typeof value === 'string' &&\n (NOTIFICATION_CATEGORIES as readonly string[]).includes(value)\n );\n}\n\n/**\n * Type guard to validate if a value is a valid NotificationLevel.\n */\nexport function isValidLevel(value: unknown): value is NotificationLevel {\n return (\n typeof value === 'string' && (NOTIFICATION_LEVELS as readonly string[]).includes(value)\n );\n}\n\n/**\n * Type guard to validate if a value is a NotifyKitNotification.\n * Use this to validate data from external sources (API responses, WebSocket messages).\n */\nexport function isNotifyKitNotification(value: unknown): value is NotifyKitNotification {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const obj = value as Record<string, unknown>;\n\n // Check required string fields\n if (typeof obj['id'] !== 'string') return false;\n if (typeof obj['key'] !== 'string') return false;\n if (typeof obj['title'] !== 'string') return false;\n if (typeof obj['body'] !== 'string') return false;\n if (typeof obj['created_at'] !== 'string') return false;\n\n // Check category and level enums\n if (!isValidCategory(obj['category'])) return false;\n if (!isValidLevel(obj['level'])) return false;\n\n // Check nullable string fields (must be string or null)\n if (obj['action_url'] !== null && typeof obj['action_url'] !== 'string') return false;\n if (obj['workspace_id'] !== null && typeof obj['workspace_id'] !== 'string') return false;\n if (obj['group_key'] !== null && typeof obj['group_key'] !== 'string') return false;\n if (obj['idempotency_key'] !== null && typeof obj['idempotency_key'] !== 'string')\n return false;\n if (obj['read_at'] !== null && typeof obj['read_at'] !== 'string') return false;\n\n // Check data is an object\n if (typeof obj['data'] !== 'object' || obj['data'] === null) {\n // data might be an empty object or missing, default to checking it's object-like\n if (obj['data'] !== undefined && (typeof obj['data'] !== 'object' || obj['data'] === null)) {\n return false;\n }\n }\n\n // Check modal is null or valid NotifyKitModalSpec\n if (obj['modal'] !== null && !isModalSpec(obj['modal'])) return false;\n\n return true;\n}\n\n/**\n * Helper to check if a notification has modal functionality enabled.\n */\nexport function isModalEnabled(notification: NotifyKitNotification): boolean {\n return notification.modal?.enabled ?? false;\n}\n","/**\n * User notification preference settings type definitions.\n */\n\nimport type { NotificationCategory } from './notification';\n\nexport type NotifyKitPreferenceBooleanMap = Readonly<Record<string, boolean>>;\n\nexport type NotifyKitPreferenceModeMap = Readonly<Record<string, string>>;\n\nexport interface NotifyKitQuietHours {\n readonly start: string;\n readonly end: string;\n}\n\nexport interface NotifyKitDigestPreferences {\n readonly enabled: boolean;\n readonly frequency: 'daily' | 'weekly';\n readonly categories: readonly NotificationCategory[] | null;\n readonly workspace_id: string | null;\n readonly timezone: string | null;\n readonly hour: number;\n readonly quiet_hours: NotifyKitQuietHours | null;\n}\n\nexport interface NotifyKitPreferenceSettings {\n readonly channels: NotifyKitPreferenceBooleanMap;\n readonly channel_modes: NotifyKitPreferenceModeMap;\n readonly topics: NotifyKitPreferenceBooleanMap;\n readonly email_preferences: NotifyKitPreferenceBooleanMap;\n readonly keyword_rules: readonly string[];\n readonly digest: NotifyKitDigestPreferences;\n readonly available_channels: readonly string[];\n readonly available_topics: readonly string[];\n readonly available_email_preferences: readonly string[];\n}\n\nexport interface NotifyKitPreferenceSettingsQuery {\n readonly workspace_id?: string | null;\n}\n\nexport interface NotifyKitPreferenceSettingsUpdate {\n readonly workspace_id?: string | null;\n readonly channels?: Record<string, boolean>;\n readonly channel_modes?: Record<string, string>;\n readonly topics?: Record<string, boolean>;\n readonly email_preferences?: Record<string, boolean>;\n readonly keyword_rules?: readonly string[];\n readonly digest?: {\n readonly enabled?: boolean;\n readonly frequency?: 'daily' | 'weekly';\n readonly categories?: readonly NotificationCategory[] | null;\n readonly timezone?: string | null;\n readonly hour?: number;\n readonly quiet_hours?: NotifyKitQuietHours | null;\n };\n}\n\nexport type NotifyKitPreferences = NotifyKitPreferenceSettings;\n\nexport type NotifyKitPreferencesUpdate = NotifyKitPreferenceSettingsUpdate;\n\nfunction isBooleanRecord(value: unknown): value is Record<string, boolean> {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n return Object.values(value).every((entry) => typeof entry === 'boolean');\n}\n\nfunction isStringRecord(value: unknown): value is Record<string, string> {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n return Object.values(value).every((entry) => typeof entry === 'string');\n}\n\nfunction isStringArray(value: unknown): value is readonly string[] {\n return Array.isArray(value) && value.every((entry) => typeof entry === 'string');\n}\n\nexport function isNotifyKitQuietHours(value: unknown): value is NotifyKitQuietHours {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const obj = value as Record<string, unknown>;\n\n return typeof obj['start'] === 'string' && typeof obj['end'] === 'string';\n}\n\nexport function isNotifyKitPreferenceSettings(\n value: unknown\n): value is NotifyKitPreferenceSettings {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const obj = value as Record<string, unknown>;\n const digest = obj['digest'];\n\n if (typeof digest !== 'object' || digest === null) {\n return false;\n }\n\n const digestRecord = digest as Record<string, unknown>;\n const quietHours = digestRecord['quiet_hours'];\n const categories = digestRecord['categories'];\n\n return (\n isBooleanRecord(obj['channels']) &&\n isStringRecord(obj['channel_modes']) &&\n isBooleanRecord(obj['topics']) &&\n isBooleanRecord(obj['email_preferences']) &&\n isStringArray(obj['keyword_rules']) &&\n typeof digestRecord['enabled'] === 'boolean' &&\n (digestRecord['frequency'] === 'daily' || digestRecord['frequency'] === 'weekly') &&\n (categories === null || isStringArray(categories)) &&\n (digestRecord['workspace_id'] === null || typeof digestRecord['workspace_id'] === 'string') &&\n (digestRecord['timezone'] === null || typeof digestRecord['timezone'] === 'string') &&\n typeof digestRecord['hour'] === 'number' &&\n (quietHours === null || isNotifyKitQuietHours(quietHours)) &&\n isStringArray(obj['available_channels']) &&\n isStringArray(obj['available_topics']) &&\n isStringArray(obj['available_email_preferences'])\n );\n}\n","/**\n * API response type definitions for Notify Kit endpoints.\n */\n\nimport type { NotifyKitNotification, NotificationCategory } from './notification';\n\n/**\n * Pagination metadata returned with list responses.\n */\nexport interface PaginationMeta {\n /** Current page number (1-indexed) */\n readonly current_page: number;\n\n /** Last page number */\n readonly last_page: number;\n\n /** Number of items per page */\n readonly per_page: number;\n\n /** Total number of items */\n readonly total: number;\n}\n\n/**\n * Response from GET /me endpoint.\n */\nexport interface NotifyKitMeResponse {\n /** The private broadcast channel for this user */\n readonly broadcast_channel: string;\n}\n\n/**\n * Response from GET /notifications endpoint.\n */\nexport interface NotifyKitListResponse {\n /** Array of notifications */\n readonly data: readonly NotifyKitNotification[];\n\n /** Pagination metadata */\n readonly meta: PaginationMeta;\n}\n\n/**\n * A grouped notification entry returned when using grouped=1 parameter.\n */\nexport interface NotifyKitGroupedEntry {\n /** The group key for this group */\n readonly group_key: string;\n\n /** Number of notifications in this group */\n readonly group_count: number;\n\n /** The most recent notification in the group */\n readonly latest_notification: NotifyKitNotification;\n\n /** IDs of all notifications in this group */\n readonly notification_ids: readonly string[];\n\n /** Whether any notification in the group is unread */\n readonly has_unread: boolean;\n}\n\n/**\n * Response from GET /notifications?grouped=1 endpoint.\n */\nexport interface NotifyKitGroupedListResponse {\n /** Array of grouped entries (may include ungrouped notifications as single-item groups) */\n readonly data: readonly NotifyKitGroupedEntry[];\n\n /** Pagination metadata */\n readonly meta: PaginationMeta;\n}\n\n/**\n * Response from GET /notifications/unread-count endpoint.\n */\nexport interface NotifyKitUnreadCountResponse {\n /** Number of unread notifications */\n readonly count: number;\n}\n\n/**\n * Response from GET /modals endpoint.\n */\nexport interface NotifyKitModalsResponse {\n /** Array of outstanding modal notifications */\n readonly data: readonly NotifyKitNotification[];\n}\n\n/**\n * Response from GET /notifications/:id endpoint.\n */\nexport interface NotifyKitSingleNotificationResponse {\n /** The requested notification */\n readonly data: NotifyKitNotification;\n}\n\n/**\n * Generic message response from mutation endpoints.\n */\nexport interface NotifyKitMutationResponse {\n /** Human-readable result message */\n readonly message: string;\n}\n\n/**\n * Response from read actions that also return the updated unread count.\n */\nexport interface NotifyKitReadMutationResponse extends NotifyKitMutationResponse {\n /** Updated unread count when supplied by the backend */\n readonly unread_count?: number;\n}\n\n/**\n * Parameters for listing notifications.\n */\nexport interface ListNotificationsParams {\n /** Filter to unread notifications only */\n readonly unread?: boolean;\n\n /** Filter by category */\n readonly category?: NotificationCategory;\n\n /** Filter by workspace ID */\n readonly workspace_id?: string;\n\n /** Enable grouped mode (Phase 2) */\n readonly grouped?: boolean;\n\n /** Page number for pagination */\n readonly page?: number;\n\n /** Number of items per page */\n readonly per_page?: number;\n}\n\n/**\n * Parameters for paginated requests.\n */\nexport interface PaginationParams {\n /** Page number (1-indexed) */\n readonly page?: number;\n\n /** Number of items per page */\n readonly per_page?: number;\n}\n\n/**\n * Standard error response from the API.\n */\nexport interface NotifyKitErrorResponse {\n /** Error message */\n readonly message: string;\n\n /** Validation errors (field -> error messages) */\n readonly errors?: Readonly<Record<string, readonly string[]>>;\n}\n\n/**\n * Type guard to validate PaginationMeta.\n */\nexport function isPaginationMeta(value: unknown): value is PaginationMeta {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const obj = value as Record<string, unknown>;\n\n return (\n typeof obj['current_page'] === 'number' &&\n typeof obj['last_page'] === 'number' &&\n typeof obj['per_page'] === 'number' &&\n typeof obj['total'] === 'number'\n );\n}\n\n/**\n * Type guard to validate NotifyKitMeResponse.\n */\nexport function isMeResponse(value: unknown): value is NotifyKitMeResponse {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const obj = value as Record<string, unknown>;\n return typeof obj['broadcast_channel'] === 'string';\n}\n\n/**\n * Type guard to validate NotifyKitUnreadCountResponse.\n */\nexport function isUnreadCountResponse(value: unknown): value is NotifyKitUnreadCountResponse {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const obj = value as Record<string, unknown>;\n return typeof obj['count'] === 'number';\n}\n\n// ============================================\n// Bulk Actions\n// ============================================\n\n/**\n * Filters for bulk operations.\n */\nexport interface BulkFilters {\n /** Filter by category */\n readonly category?: NotificationCategory;\n\n /** Filter to unread only */\n readonly unread_only?: boolean;\n}\n\n/**\n * Request body for bulk actions.\n */\nexport interface BulkActionRequest {\n /** Specific notification IDs to act on */\n readonly notification_ids?: readonly string[];\n\n /** Act on all matching notifications */\n readonly all?: boolean;\n\n /** Filters to apply when all=true */\n readonly filters?: BulkFilters;\n}\n\n/**\n * Response from bulk action endpoints.\n */\nexport interface BulkActionResult {\n /** Number of notifications affected */\n readonly affected: number;\n\n /** Number of failures */\n readonly failed: number;\n}\n\n// ============================================\n// Search\n// ============================================\n\n/**\n * Search filters for notification search.\n */\nexport interface SearchFilters {\n /** Filter by category */\n readonly category?: NotificationCategory;\n\n /** Filter to unread only */\n readonly unread?: boolean;\n\n /** Filter by level */\n readonly level?: string;\n}\n\n/**\n * Response from search endpoint.\n */\nexport interface SearchResult {\n /** Array of matching notifications */\n readonly data: readonly NotifyKitNotification[];\n\n /** Total number of matches */\n readonly total: number;\n}\n\n/**\n * A saved filter preset.\n */\nexport interface SavedFilter {\n /** Unique filter ID */\n readonly id: string;\n\n /** Display name */\n readonly name: string;\n\n /** Filter configuration */\n readonly filters: Readonly<Record<string, unknown>>;\n\n /** Whether this is a system-provided preset */\n readonly system: boolean;\n}\n\n/**\n * Response from saved filters endpoint.\n */\nexport interface SavedFiltersResponse {\n /** Array of saved filters */\n readonly data: readonly SavedFilter[];\n}\n","import type { NotifyKitNotification, NotificationCategory, NotificationLevel } from '../types';\nimport { isModalSpec } from '../types/modal';\nimport {\n isNotifyKitNotification,\n isValidCategory,\n isValidLevel,\n} from '../types/notification';\n\ninterface RawApiNotification {\n readonly id: string;\n readonly type: string | undefined;\n readonly data: Record<string, unknown>;\n readonly read_at: string | null | undefined;\n readonly created_at: string | undefined;\n}\n\nconst RESERVED_PAYLOAD_KEYS = new Set<string>([\n 'id',\n 'key',\n 'category',\n 'level',\n 'title',\n 'body',\n 'action_url',\n 'workspace_id',\n 'modal',\n 'group_key',\n 'idempotency_key',\n 'read_at',\n 'created_at',\n 'data',\n]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction nullableString(value: unknown): string | null {\n return typeof value === 'string' && value.trim() !== '' ? value : null;\n}\n\nfunction stringOrFallback(value: unknown, fallback: string): string {\n return typeof value === 'string' && value.trim() !== '' ? value : fallback;\n}\n\nfunction inferCategory(key: string): NotificationCategory {\n if (key.startsWith('workspace.')) {\n return 'workspace';\n }\n if (key.startsWith('security.')) {\n return 'security';\n }\n if (key.startsWith('orders.')) {\n return 'orders';\n }\n if (key.startsWith('social.') || key.includes('mention') || key.includes('comment')) {\n return 'social';\n }\n if (key.startsWith('marketing.')) {\n return 'marketing';\n }\n\n return 'system';\n}\n\nfunction inferLevel(value: unknown): NotificationLevel {\n if (isValidLevel(value)) {\n return value;\n }\n\n return 'info';\n}\n\nfunction buildUser(payload: Record<string, unknown>): Record<string, unknown> | undefined {\n const actorId = nullableString(payload['actor_id']);\n if (actorId === null) {\n return undefined;\n }\n\n const user: Record<string, unknown> = {\n id: actorId,\n name: stringOrFallback(payload['actor_name'], 'Someone'),\n handle: nullableString(payload['actor_handle']) ?? '',\n };\n\n const avatar = nullableString(payload['actor_avatar']);\n if (avatar !== null) {\n user['avatar'] = avatar;\n }\n\n return user;\n}\n\n/**\n * Detect a grouped notification entry returned by the grouped=1 API.\n * Grouped entries wrap a real notification inside `latest_notification`.\n */\nfunction isGroupedEntry(value: unknown): value is Record<string, unknown> & {\n latest_notification: Record<string, unknown>;\n group_key: string;\n} {\n if (!isRecord(value)) {\n return false;\n }\n\n return (\n typeof value['group_key'] === 'string' &&\n isRecord(value['latest_notification'])\n );\n}\n\n/**\n * Unwrap a grouped entry: normalize the inner notification and merge\n * group metadata (group_count, notification_ids, has_unread, group_key)\n * into its data field so the UI can access aggregation info.\n */\nfunction normalizeGroupedEntry(entry: Record<string, unknown> & {\n latest_notification: Record<string, unknown>;\n group_key: string;\n}): NotifyKitNotification {\n const inner = normalizeApiNotification(entry.latest_notification);\n\n const groupData: Record<string, unknown> = {};\n\n if (typeof entry['group_count'] === 'number') {\n groupData['group_count'] = entry['group_count'];\n }\n if (typeof entry['group_key'] === 'string') {\n groupData['group_key'] = entry['group_key'];\n }\n if (Array.isArray(entry['notification_ids'])) {\n groupData['notification_ids'] = entry['notification_ids'];\n }\n if (typeof entry['has_unread'] === 'boolean') {\n groupData['has_unread'] = entry['has_unread'];\n }\n\n return {\n ...inner,\n group_key: nullableString(entry['group_key']) ?? inner.group_key,\n read_at: entry['has_unread'] === false ? (inner.read_at ?? new Date().toISOString()) : inner.read_at,\n data: {\n ...inner.data,\n ...groupData,\n },\n };\n}\n\nexport function normalizeApiNotification(raw: unknown): NotifyKitNotification {\n if (isNotifyKitNotification(raw)) {\n return raw;\n }\n\n // Unwrap grouped notification entries (from grouped=1 API)\n if (isGroupedEntry(raw)) {\n return normalizeGroupedEntry(raw);\n }\n\n const rawRecord: RawApiNotification = isRecord(raw)\n ? {\n id: stringOrFallback(raw['id'], ''),\n type: nullableString(raw['type']) ?? undefined,\n data: isRecord(raw['data']) ? raw['data'] : {},\n read_at: nullableString(raw['read_at']),\n created_at: nullableString(raw['created_at']) ?? undefined,\n }\n : {\n id: '',\n type: undefined,\n data: {},\n read_at: undefined,\n created_at: undefined,\n };\n const payload = isRecord(rawRecord.data) ? rawRecord.data : {};\n const nestedData = isRecord(payload['data']) ? payload['data'] : {};\n const key = stringOrFallback(payload['key'], stringOrFallback(rawRecord.type, 'system.notification'));\n const category = isValidCategory(payload['category'])\n ? payload['category']\n : inferCategory(key);\n const title = stringOrFallback(payload['title'], stringOrFallback(payload['message'], 'Notification'));\n const body = stringOrFallback(payload['body'], stringOrFallback(payload['message'], title));\n const actionUrl = nullableString(payload['action_url']) ?? nullableString(payload['link']);\n const user = buildUser(payload);\n\n const data: Record<string, unknown> = {\n ...nestedData,\n };\n\n for (const [entryKey, entryValue] of Object.entries(payload)) {\n if (entryKey === 'data' || RESERVED_PAYLOAD_KEYS.has(entryKey)) {\n continue;\n }\n\n data[entryKey] = entryValue;\n }\n\n if (typeof payload['key'] === 'string') {\n data['key'] = payload['key'];\n }\n if (typeof payload['title'] === 'string') {\n data['title'] = payload['title'];\n }\n\n data['body'] = body;\n data['message'] = body;\n\n if (actionUrl !== null) {\n data['action_url'] = actionUrl;\n data['link'] = actionUrl;\n }\n\n if (user !== undefined) {\n data['user'] = user;\n }\n\n return {\n id: stringOrFallback(rawRecord.id, ''),\n key,\n category,\n level: inferLevel(payload['level']),\n title,\n body,\n action_url: actionUrl,\n workspace_id: nullableString(payload['workspace_id']),\n modal: isModalSpec(payload['modal']) ? payload['modal'] : null,\n group_key: nullableString(payload['group_key']),\n idempotency_key: nullableString(payload['idempotency_key']),\n data,\n read_at: rawRecord.read_at ?? null,\n created_at: stringOrFallback(rawRecord.created_at, new Date().toISOString()),\n };\n}\n","/**\n * Notify Kit HTTP Client\n *\n * Provides type-safe access to all Notify Kit API endpoints.\n */\n\nimport type {\n NotifyKitNotification,\n NotifyKitMeResponse,\n NotifyKitListResponse,\n NotifyKitUnreadCountResponse,\n NotifyKitSingleNotificationResponse,\n NotifyKitReadMutationResponse,\n NotifyKitPreferenceSettingsQuery,\n NotifyKitPreferences,\n NotifyKitPreferencesUpdate,\n ListNotificationsParams,\n PaginationParams,\n BulkFilters,\n BulkActionResult,\n SearchFilters,\n SearchResult,\n SavedFilter,\n SavedFiltersResponse,\n} from '../types';\nimport { normalizeApiNotification } from './normalizeNotification';\n\n/**\n * Configuration options for the NotifyKit client.\n */\nexport interface NotifyKitClientConfig {\n /** Base URL for the Notify Kit API (e.g., '/api/notify-kit' or 'https://api.example.com') */\n baseUrl: string;\n\n /** Optional function to provide auth headers for requests */\n getAuthHeaders?: () => Record<string, string> | Promise<Record<string, string>>;\n\n /** Optional custom fetch implementation (defaults to global fetch) */\n fetch?: typeof fetch;\n}\n\n/**\n * API error thrown when requests fail.\n */\nexport class NotifyKitApiError extends Error {\n public override readonly name = 'NotifyKitApiError';\n\n constructor(\n message: string,\n public readonly status: number,\n public readonly errors?: Readonly<Record<string, readonly string[]>>,\n public readonly headers?: Readonly<Record<string, string>>\n ) {\n super(message);\n }\n}\n\n/**\n * HTTP Client for the Notify Kit API.\n */\nexport class NotifyKitClient {\n private readonly baseUrl: string;\n private readonly getAuthHeaders:\n | (() => Record<string, string> | Promise<Record<string, string>>)\n | undefined;\n private readonly fetchFn: typeof fetch;\n\n constructor(config: NotifyKitClientConfig) {\n // Strip trailing slash from baseUrl\n this.baseUrl = config.baseUrl.replace(/\\/+$/, '');\n this.getAuthHeaders = config.getAuthHeaders ?? undefined;\n this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n // ============================================\n // Me\n // ============================================\n\n /**\n * Get the current user's broadcast channel information.\n */\n async getMe(): Promise<NotifyKitMeResponse> {\n return this.request<NotifyKitMeResponse>('GET', '/me');\n }\n\n // ============================================\n // Notifications\n // ============================================\n\n /**\n * List notifications for the current user.\n */\n async listNotifications(\n params?: ListNotificationsParams\n ): Promise<NotifyKitListResponse> {\n const queryParams = this.buildNotificationParams(params);\n const queryString = queryParams.toString();\n const url = queryString.length > 0 ? `/notifications?${queryString}` : '/notifications';\n const response = await this.request<{\n data: readonly unknown[];\n meta: NotifyKitListResponse['meta'];\n }>('GET', url);\n\n return {\n data: response.data.map((notification) => normalizeApiNotification(notification)),\n meta: response.meta,\n };\n }\n\n /**\n * Get the count of unread notifications.\n */\n async getUnreadCount(): Promise<NotifyKitUnreadCountResponse> {\n return this.request<NotifyKitUnreadCountResponse>(\n 'GET',\n '/notifications/unread-count'\n );\n }\n\n /**\n * Get a single notification for the current user.\n */\n async getNotification(id: string): Promise<NotifyKitNotification> {\n const response = await this.request<NotifyKitSingleNotificationResponse>(\n 'GET',\n `/notifications/${id}`\n );\n return normalizeApiNotification(response.data);\n }\n\n /**\n * Mark a notification as read.\n */\n async markRead(id: string): Promise<NotifyKitReadMutationResponse> {\n return this.request<NotifyKitReadMutationResponse>('PATCH', `/notifications/${id}/read`);\n }\n\n /**\n * Mark all notifications as read.\n */\n async markAllRead(): Promise<void> {\n await this.request<undefined>('POST', '/notifications/read-all');\n }\n\n /**\n * Delete a notification.\n */\n async deleteNotification(id: string): Promise<void> {\n await this.request<undefined>('DELETE', `/notifications/${id}`);\n }\n\n // ============================================\n // Groups (Phase 2)\n // ============================================\n\n /**\n * Mark all notifications in a group as read.\n */\n async markGroupRead(groupKey: string): Promise<void> {\n await this.request<undefined>('PATCH', `/notifications/groups/${groupKey}/read`);\n }\n\n /**\n * Get all notifications in a group.\n */\n async getGroupNotifications(\n groupKey: string,\n params?: PaginationParams\n ): Promise<NotifyKitListResponse> {\n const queryParams = new URLSearchParams();\n if (params?.page !== undefined) {\n queryParams.set('page', String(params.page));\n }\n if (params?.per_page !== undefined) {\n queryParams.set('per_page', String(params.per_page));\n }\n const queryString = queryParams.toString();\n const url =\n queryString.length > 0\n ? `/notifications/groups/${groupKey}?${queryString}`\n : `/notifications/groups/${groupKey}`;\n const response = await this.request<{\n data: readonly unknown[];\n meta: NotifyKitListResponse['meta'];\n }>('GET', url);\n\n return {\n data: response.data.map((notification) => normalizeApiNotification(notification)),\n meta: response.meta,\n };\n }\n\n // ============================================\n // Modals\n // ============================================\n\n /**\n * List outstanding modal notifications.\n */\n async listModals(): Promise<readonly NotifyKitNotification[]> {\n const response = await this.request<{ data: NotifyKitNotification[] }>(\n 'GET',\n '/modals'\n );\n return response.data;\n }\n\n /**\n * Acknowledge a modal notification.\n */\n async ackModal(id: string): Promise<void> {\n await this.request<undefined>('POST', `/modals/${id}/ack`);\n }\n\n /**\n * Snooze a modal notification.\n */\n async snoozeModal(id: string, minutes: number): Promise<void> {\n await this.request<undefined>('POST', `/modals/${id}/snooze`, { minutes });\n }\n\n // ============================================\n // Preferences\n // ============================================\n\n /**\n * Get the current user's notification preference settings.\n */\n async getPreferenceSettings(\n query?: NotifyKitPreferenceSettingsQuery\n ): Promise<NotifyKitPreferences> {\n const queryParams = new URLSearchParams();\n\n if (query?.workspace_id !== undefined && query.workspace_id !== null) {\n queryParams.set('workspace_id', query.workspace_id);\n }\n\n const queryString = queryParams.toString();\n const url =\n queryString.length > 0\n ? `/preference-settings?${queryString}`\n : '/preference-settings';\n const response = await this.request<{ data: NotifyKitPreferences }>('GET', url);\n\n return response.data;\n }\n\n /**\n * Alias for getPreferenceSettings.\n */\n async getPreferences(\n query?: NotifyKitPreferenceSettingsQuery\n ): Promise<NotifyKitPreferences> {\n return this.getPreferenceSettings(query);\n }\n\n /**\n * Update the current user's notification preference settings.\n */\n async updatePreferenceSettings(\n preferences: NotifyKitPreferencesUpdate\n ): Promise<NotifyKitPreferences> {\n const response = await this.request<{ data: NotifyKitPreferences }>(\n 'PATCH',\n '/preference-settings',\n preferences\n );\n\n return response.data;\n }\n\n /**\n * Alias for updatePreferenceSettings.\n */\n async updatePreferences(\n preferences: NotifyKitPreferencesUpdate\n ): Promise<NotifyKitPreferences> {\n return this.updatePreferenceSettings(preferences);\n }\n\n // ============================================\n // Bulk Actions\n // ============================================\n\n /**\n * Bulk mark notifications as read.\n */\n async bulkMarkRead(ids: readonly string[]): Promise<BulkActionResult> {\n return this.request<BulkActionResult>('POST', '/notifications/bulk/read', {\n notification_ids: ids,\n });\n }\n\n /**\n * Bulk mark all matching notifications as read.\n */\n async bulkMarkAllRead(filters?: BulkFilters): Promise<BulkActionResult> {\n return this.request<BulkActionResult>('POST', '/notifications/bulk/read', {\n all: true,\n filters,\n });\n }\n\n /**\n * Bulk archive notifications.\n */\n async bulkArchive(ids: readonly string[]): Promise<BulkActionResult> {\n return this.request<BulkActionResult>('POST', '/notifications/bulk/archive', {\n notification_ids: ids,\n });\n }\n\n /**\n * Bulk archive all matching notifications.\n */\n async bulkArchiveAll(filters?: BulkFilters): Promise<BulkActionResult> {\n return this.request<BulkActionResult>('POST', '/notifications/bulk/archive', {\n all: true,\n filters,\n });\n }\n\n /**\n * Bulk delete notifications.\n */\n async bulkDelete(ids: readonly string[]): Promise<BulkActionResult> {\n return this.request<BulkActionResult>('POST', '/notifications/bulk/delete', {\n notification_ids: ids,\n });\n }\n\n /**\n * Bulk delete all matching notifications.\n */\n async bulkDeleteAll(filters?: BulkFilters): Promise<BulkActionResult> {\n return this.request<BulkActionResult>('POST', '/notifications/bulk/delete', {\n all: true,\n filters,\n });\n }\n\n // ============================================\n // Search\n // ============================================\n\n /**\n * Search notifications by query.\n */\n async search(query: string, filters?: SearchFilters, limit?: number): Promise<SearchResult> {\n const queryParams = new URLSearchParams();\n queryParams.set('q', query);\n\n if (filters?.category !== undefined) {\n queryParams.set('category', filters.category);\n }\n if (filters?.unread === true) {\n queryParams.set('unread', '1');\n }\n if (filters?.level !== undefined) {\n queryParams.set('level', filters.level);\n }\n if (limit !== undefined) {\n queryParams.set('limit', String(limit));\n }\n\n const response = await this.request<SearchResult>('GET', `/notifications/search?${queryParams.toString()}`);\n\n return {\n data: response.data.map((notification) => normalizeApiNotification(notification)),\n total: response.total,\n };\n }\n\n /**\n * Get saved filters (system + custom).\n */\n async getSavedFilters(): Promise<readonly SavedFilter[]> {\n const response = await this.request<SavedFiltersResponse>('GET', '/notifications/filters');\n return response.data;\n }\n\n /**\n * Save a custom filter.\n */\n async saveFilter(name: string, filters: Record<string, unknown>): Promise<SavedFilter> {\n const response = await this.request<{ data: SavedFilter }>('POST', '/notifications/filters', {\n name,\n filters,\n });\n return response.data;\n }\n\n /**\n * Delete a custom filter.\n */\n async deleteFilter(filterId: string): Promise<void> {\n await this.request<undefined>('DELETE', `/notifications/filters/${filterId}`);\n }\n\n // ============================================\n // Archive\n // ============================================\n\n /**\n * Archive a notification.\n */\n async archiveNotification(id: string): Promise<void> {\n await this.request<undefined>('POST', `/notifications/${id}/archive`);\n }\n\n /**\n * Unarchive a notification.\n */\n async unarchiveNotification(id: string): Promise<void> {\n await this.request<undefined>('POST', `/notifications/${id}/unarchive`);\n }\n\n // ============================================\n // Private helpers\n // ============================================\n\n private buildNotificationParams(params?: ListNotificationsParams): URLSearchParams {\n const queryParams = new URLSearchParams();\n\n if (params === undefined) {\n return queryParams;\n }\n\n if (params.unread === true) {\n queryParams.set('unread', 'true');\n }\n if (params.category !== undefined) {\n queryParams.set('category', params.category);\n }\n if (params.workspace_id !== undefined) {\n queryParams.set('workspace_id', params.workspace_id);\n }\n if (params.grouped === true) {\n queryParams.set('grouped', '1');\n }\n if (params.page !== undefined) {\n queryParams.set('page', String(params.page));\n }\n if (params.per_page !== undefined) {\n queryParams.set('per_page', String(params.per_page));\n }\n\n return queryParams;\n }\n\n private async request<T>(\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',\n path: string,\n body?: unknown\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n };\n\n // Add auth headers if provided\n if (this.getAuthHeaders !== undefined) {\n const authHeaders = await this.getAuthHeaders();\n Object.assign(headers, authHeaders);\n }\n\n const requestInit: RequestInit = {\n method,\n headers,\n };\n\n if (body !== undefined) {\n requestInit.body = JSON.stringify(body);\n }\n\n const response = await this.fetchFn(url, requestInit);\n\n if (!response.ok) {\n const responseHeaders = Object.fromEntries(\n Array.from(response.headers.entries()).map(([key, value]) => [key.toLowerCase(), value])\n );\n const errorData = (await response.json()) as {\n message?: string;\n errors?: Record<string, string[]>;\n };\n throw new NotifyKitApiError(\n errorData.message ?? `Request failed with status ${String(response.status)}`,\n response.status,\n errorData.errors,\n responseHeaders\n );\n }\n\n // Handle empty responses (204 No Content, etc.)\n const text = await response.text();\n if (text.length === 0) {\n return undefined as T;\n }\n\n return JSON.parse(text) as T;\n }\n}\n\n/**\n * Create a new NotifyKit client instance.\n */\nexport function createNotifyKitClient(config: NotifyKitClientConfig): NotifyKitClient {\n return new NotifyKitClient(config);\n}\n","/**\n * Notify Kit API endpoint constants.\n *\n * These are provided for reference and debugging purposes.\n * The NotifyKitClient class handles URL construction internally.\n */\n\nexport const ENDPOINTS = {\n /** GET - Returns broadcast channel for authenticated user */\n ME: '/me',\n\n /** GET - List notifications (supports filters and pagination) */\n NOTIFICATIONS: '/notifications',\n\n /** GET - Get count of unread notifications */\n UNREAD_COUNT: '/notifications/unread-count',\n\n /** PATCH - Mark a specific notification as read */\n MARK_READ: (id: string): string => `/notifications/${id}/read`,\n\n /** POST - Mark all notifications as read */\n MARK_ALL_READ: '/notifications/read-all',\n\n /** DELETE - Delete a specific notification */\n DELETE_NOTIFICATION: (id: string): string => `/notifications/${id}`,\n\n /** PATCH - Mark all notifications in a group as read (Phase 2) */\n MARK_GROUP_READ: (groupKey: string): string =>\n `/notifications/groups/${groupKey}/read`,\n\n /** GET - Get all notifications in a group (Phase 2) */\n GROUP_NOTIFICATIONS: (groupKey: string): string =>\n `/notifications/groups/${groupKey}`,\n\n /** GET - List outstanding modal notifications */\n MODALS: '/modals',\n\n /** POST - Acknowledge a modal notification */\n ACK_MODAL: (id: string): string => `/modals/${id}/ack`,\n\n /** POST - Snooze a modal notification */\n SNOOZE_MODAL: (id: string): string => `/modals/${id}/snooze`,\n\n /** GET/PATCH - Get or update user's notification preference settings */\n PREFERENCE_SETTINGS: '/preference-settings',\n PREFERENCES: '/preference-settings',\n} as const;\n","/**\n * useNotifyKitClient composable\n *\n * Provides access to the NotifyKit HTTP client within Vue components.\n * Supports both direct configuration and provide/inject pattern.\n */\n\nimport { inject, provide, type InjectionKey } from 'vue';\nimport {\n NotifyKitClient,\n createNotifyKitClient,\n type NotifyKitClientConfig,\n} from '../client';\nimport type {\n NotifyKitMeResponse,\n NotifyKitListResponse,\n NotifyKitUnreadCountResponse,\n NotifyKitReadMutationResponse,\n NotifyKitNotification,\n NotifyKitPreferenceSettingsQuery,\n NotifyKitPreferences,\n NotifyKitPreferencesUpdate,\n ListNotificationsParams,\n PaginationParams,\n} from '../types';\n\n/**\n * Injection key for the NotifyKit client.\n */\nexport const NOTIFY_KIT_CLIENT_KEY: InjectionKey<NotifyKitClient> = Symbol(\n 'notify-kit-client'\n);\n\n/**\n * Return type of useNotifyKitClient composable.\n */\nexport interface UseNotifyKitClientReturn {\n /** The underlying NotifyKitClient instance */\n readonly client: NotifyKitClient;\n\n // Me\n getMe: () => Promise<NotifyKitMeResponse>;\n\n // Notifications\n listNotifications: (params?: ListNotificationsParams) => Promise<NotifyKitListResponse>;\n getUnreadCount: () => Promise<NotifyKitUnreadCountResponse>;\n getNotification: (id: string) => Promise<NotifyKitNotification>;\n markRead: (id: string) => Promise<NotifyKitReadMutationResponse>;\n markAllRead: () => Promise<void>;\n deleteNotification: (id: string) => Promise<void>;\n\n // Groups\n markGroupRead: (groupKey: string) => Promise<void>;\n getGroupNotifications: (\n groupKey: string,\n params?: PaginationParams\n ) => Promise<NotifyKitListResponse>;\n\n // Modals\n listModals: () => Promise<readonly NotifyKitNotification[]>;\n ackModal: (id: string) => Promise<void>;\n snoozeModal: (id: string, minutes: number) => Promise<void>;\n\n // Preferences\n getPreferenceSettings: (\n query?: NotifyKitPreferenceSettingsQuery\n ) => Promise<NotifyKitPreferences>;\n updatePreferenceSettings: (\n preferences: NotifyKitPreferencesUpdate\n ) => Promise<NotifyKitPreferences>;\n getPreferences: (query?: NotifyKitPreferenceSettingsQuery) => Promise<NotifyKitPreferences>;\n updatePreferences: (\n preferences: NotifyKitPreferencesUpdate\n ) => Promise<NotifyKitPreferences>;\n}\n\n/**\n * Provides a NotifyKitClient for injection into descendant components.\n *\n * Call this in your app's setup or a parent component to make the client\n * available to all child components via useNotifyKitClient().\n *\n * @example\n * ```typescript\n * // In App.vue setup\n * provideNotifyKitClient({\n * baseUrl: '/api/notify-kit',\n * getAuthHeaders: () => ({ Authorization: `Bearer ${token}` })\n * })\n *\n * // In any child component\n * const { listNotifications, markRead } = useNotifyKitClient()\n * ```\n */\nexport function provideNotifyKitClient(config: NotifyKitClientConfig): NotifyKitClient {\n const client = createNotifyKitClient(config);\n provide(NOTIFY_KIT_CLIENT_KEY, client);\n return client;\n}\n\n/**\n * Access the NotifyKit client within a Vue component.\n *\n * If a config is provided, creates a new client instance.\n * Otherwise, uses the client provided via provideNotifyKitClient().\n *\n * @throws Error if no client is available (neither config nor injection)\n *\n * @example\n * ```typescript\n * // Use injected client\n * const { client, getMe, listNotifications } = useNotifyKitClient()\n *\n * // Or provide config directly\n * const { client } = useNotifyKitClient({\n * baseUrl: 'https://api.example.com/notify-kit'\n * })\n * ```\n */\nexport function useNotifyKitClient(config?: NotifyKitClientConfig): UseNotifyKitClientReturn {\n let client: NotifyKitClient;\n\n if (config !== undefined) {\n // Direct config provided - create new client\n client = createNotifyKitClient(config);\n } else {\n // Try to get from injection\n const injectedClient = inject(NOTIFY_KIT_CLIENT_KEY);\n if (injectedClient === undefined) {\n throw new Error(\n 'No NotifyKit client available. Either provide config to useNotifyKitClient() ' +\n 'or call provideNotifyKitClient() in a parent component.'\n );\n }\n client = injectedClient;\n }\n\n return {\n client,\n\n // Me\n getMe: (): Promise<NotifyKitMeResponse> => client.getMe(),\n\n // Notifications\n listNotifications: (params?: ListNotificationsParams): Promise<NotifyKitListResponse> =>\n client.listNotifications(params),\n getUnreadCount: (): Promise<NotifyKitUnreadCountResponse> => client.getUnreadCount(),\n getNotification: (id: string): Promise<NotifyKitNotification> => client.getNotification(id),\n markRead: (id: string): Promise<NotifyKitReadMutationResponse> => client.markRead(id),\n markAllRead: (): Promise<void> => client.markAllRead(),\n deleteNotification: (id: string): Promise<void> => client.deleteNotification(id),\n\n // Groups\n markGroupRead: (groupKey: string): Promise<void> => client.markGroupRead(groupKey),\n getGroupNotifications: (\n groupKey: string,\n params?: PaginationParams\n ): Promise<NotifyKitListResponse> => client.getGroupNotifications(groupKey, params),\n\n // Modals\n listModals: (): Promise<readonly NotifyKitNotification[]> => client.listModals(),\n ackModal: (id: string): Promise<void> => client.ackModal(id),\n snoozeModal: (id: string, minutes: number): Promise<void> =>\n client.snoozeModal(id, minutes),\n\n // Preferences\n getPreferenceSettings: (\n query?: NotifyKitPreferenceSettingsQuery\n ): Promise<NotifyKitPreferences> => client.getPreferenceSettings(query),\n updatePreferenceSettings: (\n preferences: NotifyKitPreferencesUpdate\n ): Promise<NotifyKitPreferences> => client.updatePreferenceSettings(preferences),\n getPreferences: (\n query?: NotifyKitPreferenceSettingsQuery\n ): Promise<NotifyKitPreferences> => client.getPreferences(query),\n updatePreferences: (\n preferences: NotifyKitPreferencesUpdate\n ): Promise<NotifyKitPreferences> => client.updatePreferences(preferences),\n };\n}\n","/**\n * useNotifyKitInbox composable\n *\n * Provides higher-level notification inbox orchestration on top of the\n * low-level Notify Kit store and HTTP client.\n */\n\nimport { computed, reactive, type ComputedRef } from 'vue';\nimport type {\n ListNotificationsParams,\n NotifyKitListResponse,\n NotifyKitNotification,\n NotifyKitReadMutationResponse,\n NotifyKitUnreadCountResponse,\n} from '../types';\nimport { useNotifyKitStore } from './useNotifyKitStore';\n\nconst DEFAULT_UNREAD_COUNT_RETRY_AFTER_MS = 30000;\nconst MIN_UNREAD_COUNT_RETRY_AFTER_MS = 5000;\nconst DEFAULT_UNREAD_COUNT_TRANSIENT_RETRY_MS = 10000;\nconst MAX_UNREAD_COUNT_TRANSIENT_RETRY_MS = 120000;\nconst MIN_UNREAD_COUNT_REFRESH_INTERVAL_MS = 5000;\nconst DEFAULT_PER_PAGE = 20;\n\nexport interface NotifyKitInboxClientLike {\n listNotifications: (params?: ListNotificationsParams) => Promise<NotifyKitListResponse>;\n getUnreadCount: () => Promise<NotifyKitUnreadCountResponse>;\n getNotification: (id: string) => Promise<NotifyKitNotification>;\n markRead: (id: string) => Promise<NotifyKitReadMutationResponse>;\n markAllRead: () => Promise<void>;\n deleteNotification: (id: string) => Promise<void>;\n}\n\nexport interface UseNotifyKitInboxOptions {\n client: NotifyKitInboxClientLike;\n perPage?: number;\n grouped?: boolean;\n}\n\nexport interface UseNotifyKitInboxReturn {\n readonly notifications: ComputedRef<readonly NotifyKitNotification[]>;\n readonly unreadCount: ComputedRef<number>;\n readonly loading: ComputedRef<boolean>;\n readonly error: ComputedRef<string | null>;\n readonly hasMore: ComputedRef<boolean>;\n readonly nextPage: ComputedRef<number | null>;\n readonly isUnreadCountCoolingDown: ComputedRef<boolean>;\n\n loadUnreadCount: (force?: boolean) => Promise<boolean>;\n fetchNotifications: (\n page?: number | string | null,\n append?: boolean\n ) => Promise<readonly NotifyKitNotification[] | undefined>;\n loadMore: () => Promise<void>;\n markAsRead: (notificationId: string) => Promise<void>;\n markAllAsRead: () => Promise<void>;\n deleteNotification: (notificationId: string) => Promise<void>;\n clearAll: () => Promise<void>;\n reset: () => void;\n}\n\ninterface NotifyKitApiErrorLike {\n readonly status?: number | string;\n readonly headers?: Readonly<Record<string, string>>;\n}\n\ninterface InboxState {\n error: string | null;\n currentPage: number;\n lastPage: number;\n hasMore: boolean;\n unreadCountRetryAfterUntil: number;\n unreadCountLastLoadedAt: number;\n unreadCountTransientFailureCount: number;\n unreadCountRequest: Promise<boolean> | null;\n}\n\nfunction createInitialInboxState(): InboxState {\n return {\n error: null,\n currentPage: 0,\n lastPage: 1,\n hasMore: true,\n unreadCountRetryAfterUntil: 0,\n unreadCountLastLoadedAt: 0,\n unreadCountTransientFailureCount: 0,\n unreadCountRequest: null,\n };\n}\n\nlet inboxState: InboxState | null = null;\n\nfunction getInboxState(): InboxState {\n inboxState ??= reactive(createInitialInboxState()) as InboxState;\n return inboxState;\n}\n\nexport function resetNotifyKitInbox(): void {\n if (inboxState !== null) {\n Object.assign(inboxState, createInitialInboxState());\n }\n}\n\nfunction resolveStatusCode(statusCode: number | string | undefined): number | undefined {\n if (typeof statusCode === 'number' && Number.isFinite(statusCode)) {\n return statusCode;\n }\n\n if (typeof statusCode === 'string') {\n const parsedStatus = Number.parseInt(statusCode, 10);\n if (Number.isFinite(parsedStatus)) {\n return parsedStatus;\n }\n }\n\n return undefined;\n}\n\nfunction resolveRetryAfterMs(retryAfterHeader: unknown): number {\n if (\n typeof retryAfterHeader === 'number' &&\n Number.isFinite(retryAfterHeader) &&\n retryAfterHeader > 0\n ) {\n return Math.max(MIN_UNREAD_COUNT_RETRY_AFTER_MS, retryAfterHeader * 1000);\n }\n\n if (typeof retryAfterHeader === 'string') {\n const parsedSeconds = Number.parseInt(retryAfterHeader, 10);\n if (Number.isFinite(parsedSeconds) && parsedSeconds > 0) {\n return Math.max(MIN_UNREAD_COUNT_RETRY_AFTER_MS, parsedSeconds * 1000);\n }\n }\n\n return DEFAULT_UNREAD_COUNT_RETRY_AFTER_MS;\n}\n\nfunction isServerFailureStatus(statusCode: number | undefined): boolean {\n return typeof statusCode === 'number' && statusCode >= 500 && statusCode < 600;\n}\n\nfunction resolveTransientRetryMs(failureCount: number): number {\n const sanitizedFailureCount = Math.max(1, failureCount);\n const exponentialRetryMs =\n DEFAULT_UNREAD_COUNT_TRANSIENT_RETRY_MS * 2 ** (sanitizedFailureCount - 1);\n\n return Math.min(MAX_UNREAD_COUNT_TRANSIENT_RETRY_MS, exponentialRetryMs);\n}\n\nfunction resolveErrorMessage(error: unknown): string {\n if (error instanceof Error && error.message.length > 0) {\n return error.message;\n }\n\n if (typeof error === 'string' && error.length > 0) {\n return error;\n }\n\n return 'Request failed';\n}\n\nfunction asNotifyKitApiError(error: unknown): NotifyKitApiErrorLike | null {\n if (typeof error !== 'object' || error === null) {\n return null;\n }\n\n const status = 'status' in error ? error.status : undefined;\n const headers = 'headers' in error ? error.headers : undefined;\n const resolvedStatus =\n typeof status === 'number' || typeof status === 'string' ? status : undefined;\n const resolvedHeaders =\n typeof headers === 'object' && headers !== null\n ? (headers as Readonly<Record<string, string>>)\n : undefined;\n\n if (resolvedStatus === undefined && resolvedHeaders === undefined) {\n return {};\n }\n\n return {\n ...(resolvedStatus !== undefined ? { status: resolvedStatus } : {}),\n ...(resolvedHeaders !== undefined ? { headers: resolvedHeaders } : {}),\n };\n}\n\nexport function useNotifyKitInbox(options: UseNotifyKitInboxOptions): UseNotifyKitInboxReturn {\n const { client, perPage = DEFAULT_PER_PAGE, grouped } = options;\n\n const store = useNotifyKitStore();\n const state = getInboxState();\n\n const notifications = computed(() => store.state.notifications);\n const unreadCount = computed(() => store.state.unreadCount);\n const loading = computed(() => store.state.notificationsLoading);\n const error = computed(() => state.error);\n const hasMore = computed(() => state.hasMore);\n const nextPage = computed(() => (state.hasMore ? state.currentPage + 1 : null));\n const isUnreadCountCoolingDown = computed(\n () => Date.now() < state.unreadCountRetryAfterUntil\n );\n\n function reconcileUnreadCountForFullyLoadedList(): void {\n if (state.hasMore) {\n return;\n }\n\n const resolvedUnreadCount = store.state.notifications.filter(\n (notification) => notification.read_at === null\n ).length;\n store.setUnreadCount(resolvedUnreadCount);\n }\n\n async function loadUnreadCount(force = false): Promise<boolean> {\n if (!force && Date.now() < state.unreadCountRetryAfterUntil) {\n return false;\n }\n\n if (state.unreadCountRequest !== null) {\n return await state.unreadCountRequest;\n }\n\n const now = Date.now();\n if (!force && now - state.unreadCountLastLoadedAt < MIN_UNREAD_COUNT_REFRESH_INTERVAL_MS) {\n return true;\n }\n\n store.setUnreadCountLoading(true);\n const requestStartedAt = Date.now();\n state.unreadCountRequest = (async (): Promise<boolean> => {\n try {\n const response = await client.getUnreadCount();\n\n // Protect against stale API responses overwriting optimistic real-time\n // increments. If a real-time notification arrived while the request was\n // in-flight, the server response may not yet reflect that notification.\n // Keep the higher local count in that case.\n const realtimeIncrementDuringRequest =\n store.state.lastRealtimeIncrementAt >= requestStartedAt;\n if (realtimeIncrementDuringRequest && response.count < store.state.unreadCount) {\n state.unreadCountLastLoadedAt = Date.now();\n state.unreadCountTransientFailureCount = 0;\n state.unreadCountRetryAfterUntil = 0;\n return true;\n }\n\n store.setUnreadCount(response.count);\n state.unreadCountLastLoadedAt = Date.now();\n state.unreadCountTransientFailureCount = 0;\n state.unreadCountRetryAfterUntil = 0;\n return true;\n } catch (error) {\n const apiError = asNotifyKitApiError(error);\n const statusCode = resolveStatusCode(apiError?.status);\n\n if (statusCode === 429) {\n const retryAfterHeader = apiError?.headers?.['retry-after'];\n state.unreadCountRetryAfterUntil = Date.now() + resolveRetryAfterMs(retryAfterHeader);\n return false;\n }\n\n if (statusCode === 404) {\n store.setUnreadCount(0);\n state.unreadCountLastLoadedAt = Date.now();\n state.unreadCountTransientFailureCount = 0;\n state.unreadCountRetryAfterUntil = 0;\n return true;\n }\n\n state.unreadCountTransientFailureCount += 1;\n if (statusCode === undefined || isServerFailureStatus(statusCode)) {\n state.unreadCountRetryAfterUntil =\n Date.now() + resolveTransientRetryMs(state.unreadCountTransientFailureCount);\n return false;\n }\n\n state.unreadCountRetryAfterUntil =\n Date.now() + DEFAULT_UNREAD_COUNT_TRANSIENT_RETRY_MS;\n return false;\n } finally {\n store.setUnreadCountLoading(false);\n }\n })();\n\n const wasSuccessful = await state.unreadCountRequest.finally(() => {\n state.unreadCountRequest = null;\n });\n\n return wasSuccessful;\n }\n\n async function fetchNotifications(\n page: number | string | null = null,\n append = false\n ): Promise<readonly NotifyKitNotification[] | undefined> {\n if (store.state.notificationsLoading) {\n return undefined;\n }\n\n store.setNotificationsLoading(true);\n state.error = null;\n\n try {\n const pageNumber = page !== null ? Number(page) : 1;\n const response = await client.listNotifications({\n per_page: perPage,\n page: pageNumber,\n ...(grouped === true ? { grouped: true } : {}),\n });\n const items = [...response.data];\n\n if (append) {\n store.setNotifications([...store.state.notifications, ...items]);\n } else {\n store.setNotifications(items);\n }\n\n store.setNotificationsMeta(response.meta);\n store.setLastNotificationsSync(Date.now());\n state.currentPage = response.meta.current_page;\n state.lastPage = response.meta.last_page;\n state.hasMore = response.meta.current_page < response.meta.last_page;\n reconcileUnreadCountForFullyLoadedList();\n\n return items;\n } catch (error) {\n state.error = resolveErrorMessage(error);\n store.setNotificationsMeta(null);\n state.currentPage = 0;\n state.lastPage = 1;\n state.hasMore = false;\n\n if (!append) {\n store.setNotifications([]);\n store.setUnreadCount(0);\n }\n\n throw error;\n } finally {\n store.setNotificationsLoading(false);\n }\n }\n\n async function markAsRead(notificationId: string): Promise<void> {\n const notification = store.state.notifications.find((item) => item.id === notificationId);\n const wasUnread = notification?.read_at === null;\n const response = await client.markRead(notificationId);\n\n if (wasUnread) {\n store.markNotificationRead(notificationId);\n }\n\n if (typeof response.unread_count === 'number') {\n store.setUnreadCount(Math.max(0, response.unread_count));\n return;\n }\n\n if (wasUnread) {\n store.decrementUnreadCount();\n }\n }\n\n async function markAllAsRead(): Promise<void> {\n try {\n await client.markAllRead();\n const readTimestamp = new Date().toISOString();\n const nextNotifications = store.state.notifications.map((notification) =>\n notification.read_at === null\n ? {\n ...notification,\n read_at: readTimestamp,\n }\n : notification\n );\n\n store.setNotifications(nextNotifications);\n await loadUnreadCount(true);\n } catch (error) {\n state.error = resolveErrorMessage(error);\n throw error;\n }\n }\n\n async function deleteNotification(notificationId: string): Promise<void> {\n await client.deleteNotification(notificationId);\n\n const notification = store.state.notifications.find((item) => item.id === notificationId);\n const wasUnread = notification?.read_at === null;\n\n store.removeNotification(notificationId);\n if (wasUnread) {\n store.decrementUnreadCount();\n }\n }\n\n async function clearAll(): Promise<void> {\n try {\n await client.markAllRead();\n store.setNotifications([]);\n store.setUnreadCount(0);\n } catch (error) {\n state.error = resolveErrorMessage(error);\n throw error;\n }\n }\n\n async function loadMore(): Promise<void> {\n if (!state.hasMore || store.state.notificationsLoading) {\n return;\n }\n\n await fetchNotifications(state.currentPage + 1, true);\n }\n\n function reset(): void {\n store.reset();\n Object.assign(state, createInitialInboxState());\n }\n\n return {\n notifications,\n unreadCount,\n loading,\n error,\n hasMore,\n nextPage,\n isUnreadCountCoolingDown,\n loadUnreadCount,\n fetchNotifications,\n loadMore,\n markAsRead,\n markAllAsRead,\n deleteNotification,\n clearAll,\n reset,\n };\n}\n","/**\n * useNotifyKitRealtimeState composable\n *\n * Owns generic notification state updates for realtime payloads:\n * payload normalization, idempotent merge-by-id behavior, and unread count\n * reconciliation for realtime read/delete transitions.\n */\n\nimport { useNotifyKitStore } from './useNotifyKitStore';\nimport {\n isModalEnabled,\n isModalSpec,\n isValidCategory,\n isValidLevel,\n type NotifyKitModalSpec,\n type NotifyKitNotification,\n} from '../types';\n\nexport interface UseNotifyKitRealtimeStateReturn {\n applyIncomingPayload: (payload: unknown) => NotifyKitNotification | null;\n applyIncomingNotification: (notification: NotifyKitNotification) => void;\n handleNotificationRead: (notificationId: string) => void;\n handleNotificationDeleted: (notificationId: string) => void;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction normalizeNullableString(value: unknown): string | null | undefined {\n if (value === undefined || value === null) {\n return null;\n }\n\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction normalizeModalSpec(value: unknown): NotifyKitModalSpec | null | undefined {\n if (value === undefined || value === null) {\n return null;\n }\n\n return isModalSpec(value) ? value : undefined;\n}\n\nfunction normalizeRealtimeNotificationPayload(payload: unknown): NotifyKitNotification | null {\n if (!isRecord(payload)) {\n return null;\n }\n\n const id = payload['id'];\n const key = payload['key'];\n const category = payload['category'];\n const level = payload['level'];\n const title = payload['title'];\n const body = payload['body'];\n const createdAt = payload['created_at'];\n\n if (\n typeof id !== 'string' ||\n typeof key !== 'string' ||\n !isValidCategory(category) ||\n !isValidLevel(level) ||\n typeof title !== 'string' ||\n typeof body !== 'string' ||\n typeof createdAt !== 'string'\n ) {\n return null;\n }\n\n const data = payload['data'];\n if (data !== undefined && !isRecord(data)) {\n return null;\n }\n\n const actionUrl = normalizeNullableString(payload['action_url']);\n const workspaceId = normalizeNullableString(payload['workspace_id']);\n const groupKey = normalizeNullableString(payload['group_key']);\n const idempotencyKey = normalizeNullableString(payload['idempotency_key']);\n const readAt = normalizeNullableString(payload['read_at']);\n const modal = normalizeModalSpec(payload['modal']);\n\n if (\n actionUrl === undefined ||\n workspaceId === undefined ||\n groupKey === undefined ||\n idempotencyKey === undefined ||\n readAt === undefined ||\n modal === undefined\n ) {\n return null;\n }\n\n return {\n id,\n key,\n category,\n level,\n title,\n body,\n action_url: actionUrl,\n workspace_id: workspaceId,\n modal,\n group_key: groupKey,\n idempotency_key: idempotencyKey,\n data: data ?? {},\n read_at: readAt,\n created_at: createdAt,\n };\n}\n\nexport function useNotifyKitRealtimeState(): UseNotifyKitRealtimeStateReturn {\n const store = useNotifyKitStore();\n\n function applyIncomingNotification(notification: NotifyKitNotification): void {\n const existingIndex = store.state.notifications.findIndex((item) => item.id === notification.id);\n if (existingIndex === -1) {\n store.setNotifications([notification, ...store.state.notifications]);\n if (notification.read_at === null) {\n store.incrementUnreadCount();\n }\n } else {\n const existing = store.state.notifications[existingIndex];\n const wasRead = existing?.read_at !== null;\n const isNowRead = notification.read_at !== null;\n const nextNotifications = [...store.state.notifications];\n\n nextNotifications.splice(existingIndex, 1);\n nextNotifications.unshift(notification);\n store.setNotifications(nextNotifications);\n\n if (wasRead && !isNowRead) {\n store.incrementUnreadCount();\n } else if (!wasRead && isNowRead) {\n store.decrementUnreadCount();\n }\n }\n\n if (isModalEnabled(notification)) {\n store.enqueueModal(notification);\n }\n }\n\n function applyIncomingPayload(payload: unknown): NotifyKitNotification | null {\n const notification = normalizeRealtimeNotificationPayload(payload);\n if (notification === null) {\n return null;\n }\n\n applyIncomingNotification(notification);\n return notification;\n }\n\n function handleNotificationRead(notificationId: string): void {\n const notification = store.state.notifications.find((item) => item.id === notificationId);\n if (notification?.read_at === null) {\n store.markNotificationRead(notificationId);\n store.decrementUnreadCount();\n }\n }\n\n function handleNotificationDeleted(notificationId: string): void {\n const notification = store.state.notifications.find((item) => item.id === notificationId);\n const wasUnread = notification?.read_at === null;\n\n store.removeNotification(notificationId);\n if (wasUnread) {\n store.decrementUnreadCount();\n }\n }\n\n return {\n applyIncomingPayload,\n applyIncomingNotification,\n handleNotificationRead,\n handleNotificationDeleted,\n };\n}\n","/**\n * Toast Policy Helpers\n *\n * Provides utilities for apps to decide which notifications should\n * display as toasts vs only appear in the notification inbox, and\n * which should play sound alerts.\n */\n\nimport type { NotifyKitNotification, NotificationCategory, NotificationLevel } from '../types';\n\n/**\n * Interface for toast policy implementations.\n * Apps can implement this directly for full customization.\n */\nexport interface ToastPolicy {\n /**\n * Determines if a notification should display as a toast.\n * @param notification The notification to evaluate\n * @returns true if the notification should toast\n */\n shouldToast(notification: NotifyKitNotification): boolean;\n\n /**\n * Determines if a notification should play a sound alert.\n * @param notification The notification to evaluate\n * @returns true if the notification should play sound\n */\n shouldPlaySound(notification: NotifyKitNotification): boolean;\n}\n\n/**\n * Configuration options for creating a custom toast policy.\n */\nexport interface ToastPolicyConfig {\n /**\n * Per-category toast settings.\n * true = toast, false = don't toast\n * Categories not specified use defaults.\n */\n toastCategories?: Partial<Record<NotificationCategory, boolean>>;\n\n /**\n * Notification levels that should play sound.\n * Defaults to ['danger'].\n */\n soundLevels?: NotificationLevel[];\n\n /**\n * Categories that should always play sound regardless of level.\n * Defaults to ['security'].\n */\n soundCategories?: NotificationCategory[];\n\n /**\n * Custom shouldToast function.\n * If provided, takes precedence over toastCategories.\n */\n shouldToast?: (notification: NotifyKitNotification) => boolean;\n\n /**\n * Custom shouldPlaySound function.\n * If provided, takes precedence over soundLevels and soundCategories.\n */\n shouldPlaySound?: (notification: NotifyKitNotification) => boolean;\n}\n\n/**\n * Default category toast settings.\n * - social: false (high frequency, would be noisy)\n * - All others: true\n */\nconst DEFAULT_TOAST_CATEGORIES: Record<NotificationCategory, boolean> = {\n workspace: true,\n security: true,\n orders: true,\n social: false,\n system: true,\n marketing: true,\n};\n\n/**\n * Default levels that play sound.\n */\nconst DEFAULT_SOUND_LEVELS: NotificationLevel[] = ['danger'];\n\n/**\n * Default categories that always play sound.\n */\nconst DEFAULT_SOUND_CATEGORIES: NotificationCategory[] = ['security'];\n\n/**\n * Checks if a notification has a critical modal that requires acknowledgment.\n * Critical modals suppress toasts because the modal itself is the UX.\n */\nfunction isCriticalModal(notification: NotifyKitNotification): boolean {\n return (\n notification.modal !== null &&\n notification.modal.enabled &&\n notification.modal.requires_ack\n );\n}\n\n/**\n * Default implementation of shouldToast.\n */\nfunction defaultShouldToast(\n notification: NotifyKitNotification,\n categorySettings: Record<NotificationCategory, boolean>\n): boolean {\n // Critical modals: no toast (modal is the UX)\n if (isCriticalModal(notification)) {\n return false;\n }\n\n // Use category-specific settings\n return categorySettings[notification.category];\n}\n\n/**\n * Default implementation of shouldPlaySound.\n */\nfunction defaultShouldPlaySound(\n notification: NotifyKitNotification,\n soundLevels: NotificationLevel[],\n soundCategories: NotificationCategory[]\n): boolean {\n // Play sound if level matches\n if (soundLevels.includes(notification.level)) {\n return true;\n }\n\n // Play sound if category matches\n if (soundCategories.includes(notification.category)) {\n return true;\n }\n\n return false;\n}\n\n/**\n * The default toast policy.\n *\n * Rules:\n * - Critical modals (requires_ack): no toast (modal is the UX)\n * - Security: always toast\n * - Social: no toast by default (high frequency)\n * - All others: toast\n *\n * Sound rules:\n * - Danger level: play sound\n * - Security category: play sound\n * - All others: no sound\n */\nexport const defaultToastPolicy: ToastPolicy = {\n shouldToast(notification: NotifyKitNotification): boolean {\n return defaultShouldToast(notification, DEFAULT_TOAST_CATEGORIES);\n },\n\n shouldPlaySound(notification: NotifyKitNotification): boolean {\n return defaultShouldPlaySound(\n notification,\n DEFAULT_SOUND_LEVELS,\n DEFAULT_SOUND_CATEGORIES\n );\n },\n};\n\n/**\n * Creates a custom toast policy with the specified overrides.\n *\n * @param config Configuration options for the policy\n * @returns A ToastPolicy instance\n *\n * @example\n * ```typescript\n * // Enable toasts for social, disable for marketing\n * const policy = createToastPolicy({\n * toastCategories: {\n * social: true,\n * marketing: false,\n * },\n * });\n *\n * // Custom sound for warnings\n * const policy = createToastPolicy({\n * soundLevels: ['warning', 'danger'],\n * });\n *\n * // Fully custom logic\n * const policy = createToastPolicy({\n * shouldToast: (n) => n.level === 'danger',\n * shouldPlaySound: (n) => n.category === 'security',\n * });\n * ```\n */\nexport function createToastPolicy(config: ToastPolicyConfig): ToastPolicy {\n // Merge category settings with defaults\n const categorySettings: Record<NotificationCategory, boolean> = {\n ...DEFAULT_TOAST_CATEGORIES,\n ...config.toastCategories,\n };\n\n // Use provided arrays or defaults\n const soundLevels = config.soundLevels ?? DEFAULT_SOUND_LEVELS;\n const soundCategories = config.soundCategories ?? DEFAULT_SOUND_CATEGORIES;\n\n return {\n shouldToast(notification: NotifyKitNotification): boolean {\n // Custom function takes precedence\n if (config.shouldToast !== undefined) {\n return config.shouldToast(notification);\n }\n return defaultShouldToast(notification, categorySettings);\n },\n\n shouldPlaySound(notification: NotifyKitNotification): boolean {\n // Custom function takes precedence\n if (config.shouldPlaySound !== undefined) {\n return config.shouldPlaySound(notification);\n }\n return defaultShouldPlaySound(notification, soundLevels, soundCategories);\n },\n };\n}\n","/**\n * Helpers for resolving and binding the current user's Notify Kit\n * broadcast channel outside of a specific Vue composable.\n */\n\nexport interface NotifyKitBroadcastChannelClientLike {\n getMe: () => Promise<{ broadcast_channel: string }>;\n}\n\nexport interface NotifyKitBroadcastEchoChannelLike {\n notification: (callback: (notification: unknown) => void) => NotifyKitBroadcastEchoChannelLike;\n}\n\nexport interface NotifyKitBroadcastEchoLike {\n private: (channel: string) => NotifyKitBroadcastEchoChannelLike;\n leave: (channel: string) => void;\n}\n\nexport interface ResolveNotifyKitBroadcastChannelOptions {\n client: NotifyKitBroadcastChannelClientLike;\n channel?: string;\n}\n\nexport interface BindNotifyKitBroadcastChannelOptions {\n echo: NotifyKitBroadcastEchoLike;\n channel: string;\n onNotification: (notification: unknown) => void;\n}\n\nexport interface NotifyKitBroadcastChannelSubscription {\n readonly channel: string;\n unsubscribe: () => void;\n}\n\nexport async function resolveNotifyKitBroadcastChannel(\n options: ResolveNotifyKitBroadcastChannelOptions\n): Promise<string> {\n const { client, channel } = options;\n\n if (typeof channel === 'string' && channel.length > 0) {\n return channel;\n }\n\n const meResponse = await client.getMe();\n\n return meResponse.broadcast_channel;\n}\n\nexport function bindNotifyKitBroadcastChannel(\n options: BindNotifyKitBroadcastChannelOptions\n): NotifyKitBroadcastChannelSubscription {\n const { echo, channel, onNotification } = options;\n\n echo.private(channel).notification(onNotification);\n\n return {\n channel,\n unsubscribe: (): void => {\n echo.leave(channel);\n },\n };\n}\n","/**\n * useNotifyKitRealtime composable\n *\n * Provides real-time notification handling via Laravel Echo.\n * Manages WebSocket connection, subscribes to user's broadcast channel,\n * and updates the store when notifications are received.\n */\n\nimport { ref, computed, onMounted, onUnmounted, type Ref, type ComputedRef } from 'vue';\nimport { useNotifyKitStore, type ConnectionState } from './useNotifyKitStore';\nimport { useNotifyKitRealtimeState } from './useNotifyKitRealtimeState';\nimport {\n bindNotifyKitBroadcastChannel,\n resolveNotifyKitBroadcastChannel,\n} from '../helpers';\nimport { type NotifyKitNotification } from '../types';\n\n/**\n * Minimal Echo interface - just what we need for notifications.\n * This allows consumers to pass their own Echo instance.\n */\nexport interface EchoLike {\n private: (channel: string) => EchoChannelLike;\n leave: (channel: string) => void;\n}\n\n/**\n * Minimal Echo channel interface.\n */\nexport interface EchoChannelLike {\n notification: (callback: (notification: unknown) => void) => EchoChannelLike;\n stopListening: (event: string) => EchoChannelLike;\n}\n\n/**\n * Minimal NotifyKit client interface - just the methods we need.\n */\nexport interface NotifyKitClientLike {\n getMe: () => Promise<{ broadcast_channel: string }>;\n}\n\n/**\n * Configuration options for useNotifyKitRealtime.\n */\nexport interface UseNotifyKitRealtimeOptions {\n /**\n * Laravel Echo instance or a function that returns one.\n * Function form is useful for lazy initialization or SSR safety.\n */\n echo: EchoLike | (() => EchoLike);\n\n /**\n * NotifyKit client instance for fetching broadcast channel.\n */\n client: NotifyKitClientLike;\n\n /**\n * Whether to auto-connect when the composable is created.\n * Default: true\n */\n autoConnect?: boolean;\n\n /**\n * Callback called when a notification is received.\n * Called after store is updated.\n */\n onNotification?: (notification: NotifyKitNotification) => void;\n\n /**\n * Callback called when connection state changes.\n */\n onConnectionChange?: (state: ConnectionState) => void;\n}\n\n/**\n * Return type of useNotifyKitRealtime composable.\n */\nexport interface UseNotifyKitRealtimeReturn {\n /** Whether currently connected */\n readonly isConnected: ComputedRef<boolean>;\n\n /** Current connection state */\n readonly connectionState: Ref<ConnectionState>;\n\n /** Connect to real-time notifications */\n connect: () => Promise<void>;\n\n /** Disconnect from real-time notifications */\n disconnect: () => void;\n\n /** Disconnect and reconnect */\n reconnect: () => Promise<void>;\n}\n\n/**\n * Composable for real-time notification handling via Laravel Echo.\n *\n * @example\n * ```typescript\n * import Echo from 'laravel-echo'\n * import { useNotifyKitRealtime } from '@coding-factory/notify-kit-client'\n *\n * const echo = new Echo({ ... })\n * const client = useNotifyKitClient()\n *\n * const {\n * isConnected,\n * connectionState,\n * connect,\n * disconnect\n * } = useNotifyKitRealtime({\n * echo,\n * client: client.client,\n * onNotification: (notification) => {\n * console.log('New notification:', notification.title)\n * }\n * })\n * ```\n */\nexport function useNotifyKitRealtime(options: UseNotifyKitRealtimeOptions): UseNotifyKitRealtimeReturn {\n const {\n echo: echoOption,\n client,\n autoConnect = true,\n onNotification,\n onConnectionChange,\n } = options;\n\n // Get the store for state management\n const store = useNotifyKitStore();\n const realtimeState = useNotifyKitRealtimeState();\n\n // Local state\n const connectionState = ref<ConnectionState>('disconnected');\n const currentChannel = ref<string | null>(null);\n const isSubscribed = ref(false);\n\n // Computed\n const isConnected = computed(() => connectionState.value === 'connected');\n\n /**\n * Get the Echo instance (handles function form).\n */\n function getEcho(): EchoLike {\n return typeof echoOption === 'function' ? echoOption() : echoOption;\n }\n\n /**\n * Update connection state and notify callback.\n */\n function setConnectionState(state: ConnectionState): void {\n connectionState.value = state;\n store.setConnectionState(state);\n onConnectionChange?.(state);\n }\n\n /**\n * Handle incoming notification from Echo.\n */\n function handleNotification(payload: unknown): void {\n const notification = realtimeState.applyIncomingPayload(payload);\n if (notification === null) {\n return;\n }\n\n onNotification?.(notification);\n }\n\n /**\n * Connect to real-time notifications.\n */\n async function connect(): Promise<void> {\n // Already connected or connecting\n if (connectionState.value === 'connected' || connectionState.value === 'connecting') {\n return;\n }\n\n setConnectionState('connecting');\n\n try {\n const channel = await resolveNotifyKitBroadcastChannel({ client });\n\n // Store the channel\n currentChannel.value = channel;\n store.setBroadcastChannel(channel);\n\n // Get Echo instance and subscribe\n const echo = getEcho();\n bindNotifyKitBroadcastChannel({\n echo,\n channel,\n onNotification: handleNotification,\n });\n isSubscribed.value = true;\n\n setConnectionState('connected');\n } catch (error) {\n setConnectionState('error');\n throw error;\n }\n }\n\n /**\n * Disconnect from real-time notifications.\n */\n function disconnect(): void {\n if (currentChannel.value !== null && isSubscribed.value) {\n const echo = getEcho();\n echo.leave(currentChannel.value);\n isSubscribed.value = false;\n }\n\n setConnectionState('disconnected');\n }\n\n /**\n * Disconnect and reconnect.\n */\n async function reconnect(): Promise<void> {\n disconnect();\n await connect();\n }\n\n // Lifecycle: auto-connect on mount if enabled\n onMounted(() => {\n if (autoConnect) {\n // Use void to explicitly ignore the promise\n void connect();\n }\n });\n\n // Lifecycle: cleanup on unmount\n onUnmounted(() => {\n if (isConnected.value) {\n disconnect();\n }\n });\n\n return {\n isConnected,\n connectionState,\n connect,\n disconnect,\n reconnect,\n };\n}\n","/**\n * useNotifyKitFallback composable\n *\n * Provides fallback polling when WebSocket connection fails.\n * Automatically starts polling when disconnected and stops when reconnected.\n */\n\nimport { ref, watch, onUnmounted, type Ref } from 'vue';\nimport { useNotifyKitStore, type ConnectionState } from './useNotifyKitStore';\nimport type { NotifyKitNotification } from '../types';\nimport type { NotifyKitClient } from '../client/NotifyKitClient';\n\nexport interface FallbackConfig {\n disconnectThresholdMs: number;\n unreadCountIntervalMs: number;\n modalsIntervalMs: number;\n reconnectGracePeriodMs: number;\n}\n\nconst DEFAULT_CONFIG: FallbackConfig = {\n disconnectThresholdMs: 5000,\n unreadCountIntervalMs: 30000,\n modalsIntervalMs: 120000,\n reconnectGracePeriodMs: 2000,\n};\n\nexport interface UseNotifyKitFallbackOptions {\n client: NotifyKitClient;\n connectionState: Ref<ConnectionState>;\n config?: Partial<FallbackConfig>;\n onModalsReceived?: (modals: readonly NotifyKitNotification[]) => void;\n onUnreadCountReceived?: (count: number) => void;\n}\n\nexport interface UseNotifyKitFallbackReturn {\n readonly isPolling: Ref<boolean>;\n readonly lastPollAt: Ref<number | null>;\n startPolling: () => void;\n stopPolling: () => void;\n pollUnreadCount: () => Promise<void>;\n pollModals: () => Promise<void>;\n}\n\nexport function useNotifyKitFallback(\n options: UseNotifyKitFallbackOptions\n): UseNotifyKitFallbackReturn {\n const { client, connectionState, config: userConfig, onModalsReceived, onUnreadCountReceived } =\n options;\n\n const config: FallbackConfig = {\n ...DEFAULT_CONFIG,\n ...userConfig,\n };\n\n const store = useNotifyKitStore();\n const isPolling = ref(false);\n const lastPollAt = ref<number | null>(null);\n\n let disconnectTimer: ReturnType<typeof setTimeout> | null = null;\n let unreadCountInterval: ReturnType<typeof setInterval> | null = null;\n let modalsInterval: ReturnType<typeof setInterval> | null = null;\n let reconnectGraceTimer: ReturnType<typeof setTimeout> | null = null;\n\n async function pollUnreadCount(): Promise<void> {\n try {\n const response = await client.getUnreadCount();\n store.setUnreadCount(response.count);\n lastPollAt.value = Date.now();\n onUnreadCountReceived?.(response.count);\n } catch {\n // Ignore polling errors and rely on the next poll window.\n }\n }\n\n async function pollModals(): Promise<void> {\n try {\n const modals = await client.listModals();\n for (const modal of modals) {\n store.enqueueModal(modal);\n }\n store.setLastModalsSync(Date.now());\n lastPollAt.value = Date.now();\n onModalsReceived?.(modals);\n } catch {\n // Ignore polling errors and rely on the next poll window.\n }\n }\n\n function startPolling(): void {\n if (isPolling.value) {\n return;\n }\n\n isPolling.value = true;\n void pollUnreadCount();\n void pollModals();\n\n unreadCountInterval = setInterval(() => {\n void pollUnreadCount();\n }, config.unreadCountIntervalMs);\n\n modalsInterval = setInterval(() => {\n void pollModals();\n }, config.modalsIntervalMs);\n }\n\n function stopPolling(): void {\n if (!isPolling.value) {\n return;\n }\n\n isPolling.value = false;\n\n if (unreadCountInterval !== null) {\n clearInterval(unreadCountInterval);\n unreadCountInterval = null;\n }\n\n if (modalsInterval !== null) {\n clearInterval(modalsInterval);\n modalsInterval = null;\n }\n }\n\n function clearAllTimers(): void {\n if (disconnectTimer !== null) {\n clearTimeout(disconnectTimer);\n disconnectTimer = null;\n }\n\n if (reconnectGraceTimer !== null) {\n clearTimeout(reconnectGraceTimer);\n reconnectGraceTimer = null;\n }\n }\n\n function handleConnectionStateChange(state: ConnectionState): void {\n if (state === 'disconnected' || state === 'error') {\n if (reconnectGraceTimer !== null) {\n clearTimeout(reconnectGraceTimer);\n reconnectGraceTimer = null;\n }\n\n disconnectTimer ??= setTimeout(() => {\n startPolling();\n disconnectTimer = null;\n }, config.disconnectThresholdMs);\n return;\n }\n\n if (state === 'connected') {\n if (disconnectTimer !== null) {\n clearTimeout(disconnectTimer);\n disconnectTimer = null;\n }\n\n if (isPolling.value) {\n reconnectGraceTimer = setTimeout(() => {\n stopPolling();\n void pollUnreadCount();\n void pollModals();\n reconnectGraceTimer = null;\n }, config.reconnectGracePeriodMs);\n }\n }\n }\n\n watch(connectionState, handleConnectionStateChange, { immediate: true });\n\n onUnmounted(() => {\n clearAllTimers();\n stopPolling();\n });\n\n return {\n isPolling,\n lastPollAt,\n startPolling,\n stopPolling,\n pollUnreadCount,\n pollModals,\n };\n}\n","/**\n * useNotifyKitBulkActions composable\n *\n * Provides state and methods for bulk notification operations.\n */\n\nimport { reactive, readonly, computed, type ComputedRef } from 'vue';\nimport type { BulkFilters, BulkActionResult } from '../types';\nimport type { NotifyKitClient } from '../client/NotifyKitClient';\nimport { useNotifyKitStore } from './useNotifyKitStore';\n\nexport interface BulkActionsState {\n readonly selectedIds: ReadonlySet<string>;\n readonly isSelectionMode: boolean;\n readonly isProcessing: boolean;\n readonly error: string | null;\n}\n\ninterface MutableBulkActionsState {\n selectedIds: Set<string>;\n isSelectionMode: boolean;\n isProcessing: boolean;\n error: string | null;\n}\n\nexport interface UseNotifyKitBulkActionsOptions {\n readonly client: NotifyKitClient;\n}\n\nexport interface UseNotifyKitBulkActionsReturn {\n readonly state: BulkActionsState;\n readonly selectedCount: ComputedRef<number>;\n readonly hasSelection: ComputedRef<boolean>;\n readonly selectedIdsArray: ComputedRef<readonly string[]>;\n toggleSelection: (id: string) => void;\n select: (id: string) => void;\n deselect: (id: string) => void;\n selectAll: (ids: readonly string[]) => void;\n clearSelection: () => void;\n enterSelectionMode: () => void;\n exitSelectionMode: () => void;\n markSelectedRead: () => Promise<BulkActionResult>;\n markAllRead: (filters?: BulkFilters) => Promise<BulkActionResult>;\n archiveSelected: () => Promise<BulkActionResult>;\n archiveAll: (filters?: BulkFilters) => Promise<BulkActionResult>;\n deleteSelected: () => Promise<BulkActionResult>;\n deleteAll: (filters?: BulkFilters) => Promise<BulkActionResult>;\n reset: () => void;\n}\n\nfunction createInitialState(): MutableBulkActionsState {\n return {\n selectedIds: new Set<string>(),\n isSelectionMode: false,\n isProcessing: false,\n error: null,\n };\n}\n\nexport function useNotifyKitBulkActions(\n options: UseNotifyKitBulkActionsOptions\n): UseNotifyKitBulkActionsReturn {\n const { client } = options;\n const store = useNotifyKitStore();\n const state = reactive(createInitialState());\n\n const selectedCount = computed(() => state.selectedIds.size);\n const hasSelection = computed(() => state.selectedIds.size > 0);\n const selectedIdsArray = computed(() => Array.from(state.selectedIds));\n\n function toggleSelection(id: string): void {\n if (state.selectedIds.has(id)) {\n state.selectedIds.delete(id);\n } else {\n state.selectedIds.add(id);\n }\n }\n\n function select(id: string): void {\n state.selectedIds.add(id);\n }\n\n function deselect(id: string): void {\n state.selectedIds.delete(id);\n }\n\n function selectAll(ids: readonly string[]): void {\n for (const id of ids) {\n state.selectedIds.add(id);\n }\n }\n\n function clearSelection(): void {\n state.selectedIds.clear();\n }\n\n function enterSelectionMode(): void {\n state.isSelectionMode = true;\n }\n\n function exitSelectionMode(): void {\n state.isSelectionMode = false;\n state.selectedIds.clear();\n }\n\n async function markSelectedRead(): Promise<BulkActionResult> {\n if (state.selectedIds.size === 0) {\n return { affected: 0, failed: 0 };\n }\n\n state.isProcessing = true;\n state.error = null;\n\n try {\n const ids = Array.from(state.selectedIds);\n const result = await client.bulkMarkRead(ids);\n\n for (const id of ids) {\n store.markNotificationRead(id);\n }\n\n if (result.affected > 0) {\n store.setUnreadCount(Math.max(0, store.state.unreadCount - result.affected));\n }\n\n clearSelection();\n return result;\n } catch (error) {\n state.error = error instanceof Error ? error.message : 'Failed to mark as read';\n throw error;\n } finally {\n state.isProcessing = false;\n }\n }\n\n async function markAllRead(filters?: BulkFilters): Promise<BulkActionResult> {\n state.isProcessing = true;\n state.error = null;\n\n try {\n const result = await client.bulkMarkAllRead(filters);\n if (filters === undefined) {\n store.setUnreadCount(0);\n }\n clearSelection();\n return result;\n } catch (error) {\n state.error = error instanceof Error ? error.message : 'Failed to mark all as read';\n throw error;\n } finally {\n state.isProcessing = false;\n }\n }\n\n async function archiveSelected(): Promise<BulkActionResult> {\n if (state.selectedIds.size === 0) {\n return { affected: 0, failed: 0 };\n }\n\n state.isProcessing = true;\n state.error = null;\n\n try {\n const ids = Array.from(state.selectedIds);\n const result = await client.bulkArchive(ids);\n\n for (const id of ids) {\n store.removeNotification(id);\n }\n\n clearSelection();\n return result;\n } catch (error) {\n state.error = error instanceof Error ? error.message : 'Failed to archive';\n throw error;\n } finally {\n state.isProcessing = false;\n }\n }\n\n async function archiveAll(filters?: BulkFilters): Promise<BulkActionResult> {\n state.isProcessing = true;\n state.error = null;\n\n try {\n const result = await client.bulkArchiveAll(filters);\n clearSelection();\n return result;\n } catch (error) {\n state.error = error instanceof Error ? error.message : 'Failed to archive all';\n throw error;\n } finally {\n state.isProcessing = false;\n }\n }\n\n async function deleteSelected(): Promise<BulkActionResult> {\n if (state.selectedIds.size === 0) {\n return { affected: 0, failed: 0 };\n }\n\n state.isProcessing = true;\n state.error = null;\n\n try {\n const ids = Array.from(state.selectedIds);\n const result = await client.bulkDelete(ids);\n\n for (const id of ids) {\n store.removeNotification(id);\n }\n\n clearSelection();\n return result;\n } catch (error) {\n state.error = error instanceof Error ? error.message : 'Failed to delete';\n throw error;\n } finally {\n state.isProcessing = false;\n }\n }\n\n async function deleteAll(filters?: BulkFilters): Promise<BulkActionResult> {\n state.isProcessing = true;\n state.error = null;\n\n try {\n const result = await client.bulkDeleteAll(filters);\n clearSelection();\n return result;\n } catch (error) {\n state.error = error instanceof Error ? error.message : 'Failed to delete all';\n throw error;\n } finally {\n state.isProcessing = false;\n }\n }\n\n function reset(): void {\n Object.assign(state, createInitialState());\n }\n\n return {\n state: readonly(state) as BulkActionsState,\n selectedCount,\n hasSelection,\n selectedIdsArray,\n toggleSelection,\n select,\n deselect,\n selectAll,\n clearSelection,\n enterSelectionMode,\n exitSelectionMode,\n markSelectedRead,\n markAllRead,\n archiveSelected,\n archiveAll,\n deleteSelected,\n deleteAll,\n reset,\n };\n}\n","/**\n * useNotifyKitSearch composable\n *\n * Provides state and methods for notification search functionality.\n */\n\nimport { reactive, readonly, computed, ref, type ComputedRef, type Ref } from 'vue';\nimport type { NotifyKitNotification, SearchFilters, SavedFilter } from '../types';\nimport type { NotifyKitClient } from '../client/NotifyKitClient';\n\nexport interface SearchState {\n readonly query: string;\n readonly results: readonly NotifyKitNotification[];\n readonly total: number;\n readonly isSearching: boolean;\n readonly hasSearched: boolean;\n readonly filters: SearchFilters | null;\n readonly error: string | null;\n}\n\ninterface MutableSearchState {\n query: string;\n results: NotifyKitNotification[];\n total: number;\n isSearching: boolean;\n hasSearched: boolean;\n filters: SearchFilters | null;\n error: string | null;\n}\n\nexport interface UseNotifyKitSearchOptions {\n readonly client: NotifyKitClient;\n readonly minQueryLength?: number;\n readonly debounceMs?: number;\n}\n\nexport interface UseNotifyKitSearchReturn {\n readonly state: SearchState;\n readonly hasResults: ComputedRef<boolean>;\n readonly resultCount: ComputedRef<number>;\n readonly isValidQuery: ComputedRef<boolean>;\n readonly savedFilters: Ref<readonly SavedFilter[]>;\n readonly savedFiltersLoading: Ref<boolean>;\n search: (query: string, filters?: SearchFilters) => Promise<void>;\n clearSearch: () => void;\n setFilters: (filters: SearchFilters | null) => void;\n loadSavedFilters: () => Promise<void>;\n applyFilter: (filter: SavedFilter) => Promise<void>;\n saveFilter: (name: string, filters: Record<string, unknown>) => Promise<SavedFilter>;\n deleteFilter: (filterId: string) => Promise<void>;\n reset: () => void;\n}\n\nfunction createInitialState(): MutableSearchState {\n return {\n query: '',\n results: [],\n total: 0,\n isSearching: false,\n hasSearched: false,\n filters: null,\n error: null,\n };\n}\n\nexport function useNotifyKitSearch(options: UseNotifyKitSearchOptions): UseNotifyKitSearchReturn {\n const { client, minQueryLength = 3 } = options;\n const state = reactive(createInitialState());\n const savedFilters = ref<readonly SavedFilter[]>([]);\n const savedFiltersLoading = ref(false);\n\n const hasResults = computed(() => state.results.length > 0);\n const resultCount = computed(() => state.results.length);\n const isValidQuery = computed(() => state.query.length >= minQueryLength);\n\n async function search(query: string, filters?: SearchFilters): Promise<void> {\n state.query = query;\n\n if (query.length < minQueryLength) {\n state.error = `Search query must be at least ${String(minQueryLength)} characters`;\n return;\n }\n\n state.isSearching = true;\n state.error = null;\n\n try {\n const effectiveFilters = filters ?? state.filters ?? undefined;\n const result = await client.search(query, effectiveFilters);\n\n state.results = [...result.data];\n state.total = result.total;\n state.hasSearched = true;\n\n if (filters !== undefined) {\n state.filters = filters;\n }\n } catch (error) {\n state.error = error instanceof Error ? error.message : 'Search failed';\n state.results = [];\n state.total = 0;\n } finally {\n state.isSearching = false;\n }\n }\n\n function clearSearch(): void {\n state.query = '';\n state.results = [];\n state.total = 0;\n state.hasSearched = false;\n state.error = null;\n }\n\n function setFilters(filters: SearchFilters | null): void {\n state.filters = filters;\n }\n\n async function loadSavedFilters(): Promise<void> {\n savedFiltersLoading.value = true;\n\n try {\n savedFilters.value = await client.getSavedFilters();\n } catch {\n // Keep existing filters if loading fails.\n } finally {\n savedFiltersLoading.value = false;\n }\n }\n\n async function applyFilter(filter: SavedFilter): Promise<void> {\n const searchFilters: SearchFilters = {};\n const categoryValue = filter.filters['category'];\n const levelValue = filter.filters['level'];\n\n if (typeof categoryValue === 'string') {\n (searchFilters as { category?: string }).category = categoryValue;\n }\n\n if (filter.filters['unread_only'] === true) {\n (searchFilters as { unread?: boolean }).unread = true;\n }\n\n if (typeof levelValue === 'string') {\n (searchFilters as { level?: string }).level = levelValue;\n }\n\n state.filters = searchFilters;\n\n if (state.query.length >= minQueryLength) {\n await search(state.query, searchFilters);\n }\n }\n\n async function saveFilter(name: string, filters: Record<string, unknown>): Promise<SavedFilter> {\n const createdFilter = await client.saveFilter(name, filters);\n savedFilters.value = [...savedFilters.value, createdFilter];\n return createdFilter;\n }\n\n async function deleteFilter(filterId: string): Promise<void> {\n await client.deleteFilter(filterId);\n savedFilters.value = savedFilters.value.filter((filter) => filter.id !== filterId);\n }\n\n function reset(): void {\n Object.assign(state, createInitialState());\n savedFilters.value = [];\n }\n\n return {\n state: readonly(state) as SearchState,\n hasResults,\n resultCount,\n isValidQuery,\n savedFilters,\n savedFiltersLoading,\n search,\n clearSearch,\n setFilters,\n loadSavedFilters,\n applyFilter,\n saveFilter,\n deleteFilter,\n reset,\n };\n}\n","/**\n * @coding-factory/notify-kit-client\n *\n * Headless Vue 3/Nuxt client for Notify Kit notifications.\n * Provides TypeScript types, HTTP client, composables, and Nuxt integration.\n */\n\n// Version export for debugging\nexport const VERSION = '0.2.2';\n\n// Types - matching backend payload contract exactly\nexport * from './types';\n\n// HTTP Client\nexport * from './client';\n\n// Vue 3 Composables\nexport * from './composables';\n\n// Helpers\nexport * from './helpers';\n"]}
@@ -1,5 +1,5 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
- import { T as UseNotifyKitStoreReturn, a as NotifyKitClient, R as UseNotifyKitModalsReturn } from '../useNotifyKitModals-CWHM9rYY.js';
2
+ import { T as UseNotifyKitStoreReturn, a as NotifyKitClient, R as UseNotifyKitModalsReturn } from '../useNotifyKitModals-DFF8yJeq.js';
3
3
  import 'vue';
4
4
 
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { useNotifyKitStore, useNotifyKitModals } from '../chunk-7LQBNDRD.js';
1
+ import { useNotifyKitStore, useNotifyKitModals } from '../chunk-GBBCD3P6.js';
2
2
  import { defineNuxtModule, createResolver, addPlugin, addImports } from '@nuxt/kit';
3
3
  import { useNuxtApp } from '#app';
4
4
 
@@ -539,6 +539,7 @@ interface NotifyKitStoreState {
539
539
  readonly notificationsMeta: PaginationMeta | null;
540
540
  readonly unreadCount: number;
541
541
  readonly unreadCountLoading: boolean;
542
+ readonly lastRealtimeIncrementAt: number;
542
543
  readonly modalQueue: readonly NotifyKitNotification[];
543
544
  readonly modalsLoading: boolean;
544
545
  readonly broadcastChannel: string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codingfactory/notify-kit-client",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Headless Vue 3/Nuxt client for Notify Kit notifications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/composables/useNotifyKitStore.ts","../src/composables/useNotifyKitModals.ts"],"names":["provide","computed"],"mappings":"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","file":"chunk-7LQBNDRD.js","sourcesContent":["/**\n * useNotifyKitStore composable\n *\n * Provides a reactive store for NotifyKit state management.\n * Manages notifications, unread counts, modal queue, and connection state.\n * Uses singleton pattern to share state across components.\n */\n\nimport { reactive, readonly, computed, provide, type InjectionKey, type ComputedRef } from 'vue';\nimport type { NotifyKitNotification, PaginationMeta } from '../types';\n\n/**\n * Connection state for real-time subscriptions.\n */\nexport type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'error';\n\n/**\n * Store state shape.\n */\nexport interface NotifyKitStoreState {\n // Notifications\n readonly notifications: readonly NotifyKitNotification[];\n readonly notificationsLoading: boolean;\n readonly notificationsMeta: PaginationMeta | null;\n\n // Unread\n readonly unreadCount: number;\n readonly unreadCountLoading: boolean;\n\n // Modals\n readonly modalQueue: readonly NotifyKitNotification[];\n readonly modalsLoading: boolean;\n\n // Connection\n readonly broadcastChannel: string | null;\n readonly connectionState: ConnectionState;\n\n // Sync timestamps\n readonly lastNotificationsSync: number | null;\n readonly lastModalsSync: number | null;\n}\n\n/**\n * Internal mutable state shape.\n */\ninterface MutableStoreState {\n notifications: NotifyKitNotification[];\n notificationsLoading: boolean;\n notificationsMeta: PaginationMeta | null;\n unreadCount: number;\n unreadCountLoading: boolean;\n modalQueue: NotifyKitNotification[];\n modalsLoading: boolean;\n broadcastChannel: string | null;\n connectionState: ConnectionState;\n lastNotificationsSync: number | null;\n lastModalsSync: number | null;\n}\n\n/**\n * Return type of useNotifyKitStore composable.\n */\nexport interface UseNotifyKitStoreReturn {\n /** Readonly reactive state */\n readonly state: NotifyKitStoreState;\n\n /** Computed: whether there are unread notifications */\n readonly hasUnread: ComputedRef<boolean>;\n\n /** Computed: the current (first) modal in queue, or null */\n readonly currentModal: ComputedRef<NotifyKitNotification | null>;\n\n /** Computed: whether there are modals in the queue */\n readonly hasModals: ComputedRef<boolean>;\n\n // Notification mutations\n addNotification: (notification: NotifyKitNotification) => void;\n setNotifications: (notifications: readonly NotifyKitNotification[]) => void;\n markNotificationRead: (id: string) => void;\n removeNotification: (id: string) => void;\n\n // Unread count mutations\n setUnreadCount: (count: number) => void;\n incrementUnreadCount: () => void;\n decrementUnreadCount: () => void;\n\n // Modal queue mutations\n enqueueModal: (notification: NotifyKitNotification) => void;\n dequeueModal: (id: string) => void;\n clearModalQueue: () => void;\n\n // Connection mutations\n setConnectionState: (state: ConnectionState) => void;\n setBroadcastChannel: (channel: string) => void;\n\n // Loading state mutations\n setNotificationsLoading: (loading: boolean) => void;\n setUnreadCountLoading: (loading: boolean) => void;\n setModalsLoading: (loading: boolean) => void;\n\n // Meta mutations\n setNotificationsMeta: (meta: PaginationMeta | null) => void;\n\n // Sync timestamp mutations\n setLastNotificationsSync: (timestamp: number | null) => void;\n setLastModalsSync: (timestamp: number | null) => void;\n\n // Reset\n reset: () => void;\n}\n\n/**\n * Injection key for the NotifyKit store.\n */\nexport const NOTIFY_KIT_STORE_KEY: InjectionKey<UseNotifyKitStoreReturn> = Symbol('notify-kit-store');\n\n/**\n * Creates the initial store state.\n */\nfunction createInitialState(): MutableStoreState {\n return {\n notifications: [],\n notificationsLoading: false,\n notificationsMeta: null,\n unreadCount: 0,\n unreadCountLoading: false,\n modalQueue: [],\n modalsLoading: false,\n broadcastChannel: null,\n connectionState: 'disconnected',\n lastNotificationsSync: null,\n lastModalsSync: null,\n };\n}\n\n// Singleton store state\nlet storeState: MutableStoreState | null = null;\n\n/**\n * Gets or creates the singleton store state.\n */\nfunction getStoreState(): MutableStoreState {\n storeState ??= reactive(createInitialState());\n return storeState;\n}\n\n/**\n * Resets the store state to initial values.\n * Primarily used for testing to ensure clean state between tests.\n */\nexport function resetNotifyKitStore(): void {\n if (storeState !== null) {\n Object.assign(storeState, createInitialState());\n }\n}\n\n/**\n * Creates the store return object with all actions and computed properties.\n */\nfunction createStoreReturn(state: MutableStoreState): UseNotifyKitStoreReturn {\n // Computed properties\n const hasUnread = computed(() => state.unreadCount > 0);\n const currentModal = computed(() => state.modalQueue[0] ?? null);\n const hasModals = computed(() => state.modalQueue.length > 0);\n\n return {\n // State as readonly\n state: readonly(state) as NotifyKitStoreState,\n\n // Computed\n hasUnread,\n currentModal,\n hasModals,\n\n // Notification mutations\n addNotification: (notification: NotifyKitNotification): void => {\n state.notifications.unshift(notification);\n },\n\n setNotifications: (notifications: readonly NotifyKitNotification[]): void => {\n state.notifications = [...notifications];\n },\n\n markNotificationRead: (id: string): void => {\n const index = state.notifications.findIndex((n) => n.id === id);\n if (index !== -1) {\n const notification = state.notifications[index];\n if (notification !== undefined) {\n state.notifications[index] = {\n ...notification,\n read_at: new Date().toISOString(),\n };\n }\n }\n },\n\n removeNotification: (id: string): void => {\n const index = state.notifications.findIndex((n) => n.id === id);\n if (index !== -1) {\n state.notifications.splice(index, 1);\n }\n },\n\n // Unread count mutations\n setUnreadCount: (count: number): void => {\n state.unreadCount = count;\n },\n\n incrementUnreadCount: (): void => {\n state.unreadCount += 1;\n },\n\n decrementUnreadCount: (): void => {\n if (state.unreadCount > 0) {\n state.unreadCount -= 1;\n }\n },\n\n // Modal queue mutations\n enqueueModal: (notification: NotifyKitNotification): void => {\n // Don't add duplicates\n const exists = state.modalQueue.some((m) => m.id === notification.id);\n if (!exists) {\n state.modalQueue.push(notification);\n }\n },\n\n dequeueModal: (id: string): void => {\n const index = state.modalQueue.findIndex((m) => m.id === id);\n if (index !== -1) {\n state.modalQueue.splice(index, 1);\n }\n },\n\n clearModalQueue: (): void => {\n state.modalQueue = [];\n },\n\n // Connection mutations\n setConnectionState: (connectionState: ConnectionState): void => {\n state.connectionState = connectionState;\n },\n\n setBroadcastChannel: (channel: string): void => {\n state.broadcastChannel = channel;\n },\n\n // Loading state mutations\n setNotificationsLoading: (loading: boolean): void => {\n state.notificationsLoading = loading;\n },\n\n setUnreadCountLoading: (loading: boolean): void => {\n state.unreadCountLoading = loading;\n },\n\n setModalsLoading: (loading: boolean): void => {\n state.modalsLoading = loading;\n },\n\n // Meta mutations\n setNotificationsMeta: (meta: PaginationMeta | null): void => {\n state.notificationsMeta = meta;\n },\n\n // Sync timestamp mutations\n setLastNotificationsSync: (timestamp: number | null): void => {\n state.lastNotificationsSync = timestamp;\n },\n\n setLastModalsSync: (timestamp: number | null): void => {\n state.lastModalsSync = timestamp;\n },\n\n // Reset\n reset: (): void => {\n Object.assign(state, createInitialState());\n },\n };\n}\n\n/**\n * Provides the NotifyKit store for injection into descendant components.\n *\n * Call this in your app's setup or a parent component to make the store\n * available to all child components via useNotifyKitStore().\n *\n * @example\n * ```typescript\n * // In App.vue setup\n * const store = provideNotifyKitStore()\n *\n * // In any child component\n * const { state, addNotification } = useNotifyKitStore()\n * ```\n */\nexport function provideNotifyKitStore(): UseNotifyKitStoreReturn {\n const state = getStoreState();\n const store = createStoreReturn(state);\n provide(NOTIFY_KIT_STORE_KEY, store);\n return store;\n}\n\n/**\n * Access the NotifyKit store within a Vue component.\n *\n * Uses a singleton pattern to share state across all components.\n *\n * @example\n * ```typescript\n * const {\n * state,\n * hasUnread,\n * currentModal,\n * addNotification,\n * markNotificationRead\n * } = useNotifyKitStore()\n * ```\n */\nexport function useNotifyKitStore(): UseNotifyKitStoreReturn {\n const state = getStoreState();\n return createStoreReturn(state);\n}\n","/**\n * useNotifyKitModals composable\n *\n * Provides modal queue management for critical notifications.\n * Handles loading outstanding modals, acknowledgement, and snoozing.\n */\n\nimport { computed, provide, type ComputedRef, type InjectionKey, type Ref } from 'vue';\nimport { useNotifyKitStore } from './useNotifyKitStore';\nimport type { NotifyKitNotification } from '../types';\n\n/**\n * Minimal NotifyKit client interface - just the modal methods.\n */\nexport interface NotifyKitModalsClientLike {\n listModals: () => Promise<readonly NotifyKitNotification[]>;\n ackModal: (id: string) => Promise<void>;\n snoozeModal: (id: string, minutes: number) => Promise<void>;\n}\n\n/**\n * Configuration options for useNotifyKitModals.\n */\nexport interface UseNotifyKitModalsOptions {\n /**\n * NotifyKit client instance for modal API calls.\n */\n client: NotifyKitModalsClientLike;\n}\n\n/**\n * Return type of useNotifyKitModals composable.\n */\nexport interface UseNotifyKitModalsReturn {\n /** The current (first) modal in queue, or null */\n readonly currentModal: ComputedRef<NotifyKitNotification | null>;\n\n /** All modals in the queue */\n readonly modalQueue: ComputedRef<readonly NotifyKitNotification[]>;\n\n /** Whether there are modals in the queue */\n readonly hasModals: ComputedRef<boolean>;\n\n /** Whether modals are currently being loaded */\n readonly isLoading: Ref<boolean>;\n\n /** Load outstanding modals from the API */\n loadOutstandingModals: () => Promise<void>;\n\n /** Acknowledge a modal (removes from queue) */\n ack: (id: string) => Promise<void>;\n\n /** Snooze a modal (removes from queue temporarily) */\n snooze: (id: string, minutes: number) => Promise<void>;\n\n /** Acknowledge the current modal */\n dismissCurrent: () => Promise<void>;\n\n /** Snooze the current modal */\n snoozeCurrent: (minutes: number) => Promise<void>;\n\n /** Get allowed snooze options for a notification */\n getSnoozeOptions: (notification: NotifyKitNotification) => readonly number[];\n}\n\n/**\n * Error thrown when an invalid snooze duration is provided.\n */\nexport class InvalidSnoozeDurationError extends Error {\n public override readonly name = 'InvalidSnoozeDurationError';\n\n constructor(minutes: number, allowedMinutes: readonly number[]) {\n super(`Invalid snooze duration: ${String(minutes)}. Allowed values: ${allowedMinutes.join(', ')}`);\n }\n}\n\n/**\n * Injection key for the NotifyKit modals composable.\n */\nexport const NOTIFY_KIT_MODALS_KEY: InjectionKey<UseNotifyKitModalsReturn> = Symbol('notify-kit-modals');\n\n/**\n * Provides NotifyKit modals management for injection into descendant components.\n *\n * @example\n * ```typescript\n * // In App.vue setup\n * const modals = provideNotifyKitModals({ client })\n *\n * // In any child component\n * const { currentModal, dismissCurrent } = useNotifyKitModals({ client })\n * ```\n */\nexport function provideNotifyKitModals(options: UseNotifyKitModalsOptions): UseNotifyKitModalsReturn {\n const modals = useNotifyKitModals(options);\n provide(NOTIFY_KIT_MODALS_KEY, modals);\n return modals;\n}\n\n/**\n * Composable for managing modal notification queue.\n *\n * Handles loading outstanding modals from the API, acknowledging them,\n * and snoozing them. Uses the store for reactive queue management.\n *\n * @example\n * ```typescript\n * const {\n * currentModal,\n * hasModals,\n * loadOutstandingModals,\n * dismissCurrent,\n * snoozeCurrent,\n * getSnoozeOptions\n * } = useNotifyKitModals({ client })\n *\n * // Load modals on login\n * await loadOutstandingModals()\n *\n * // Handle current modal\n * if (currentModal.value) {\n * const options = getSnoozeOptions(currentModal.value)\n * // Show modal with snooze options...\n * }\n *\n * // User acknowledges\n * await dismissCurrent()\n *\n * // Or user snoozes for 1 hour\n * await snoozeCurrent(60)\n * ```\n */\nexport function useNotifyKitModals(options: UseNotifyKitModalsOptions): UseNotifyKitModalsReturn {\n const { client } = options;\n\n // Get the store for state management\n const store = useNotifyKitStore();\n\n // Computed properties from store\n const currentModal = computed(() => store.currentModal.value);\n const modalQueue = computed(() => store.state.modalQueue);\n const hasModals = computed(() => store.hasModals.value);\n const isLoading = computed(() => store.state.modalsLoading);\n\n /**\n * Load outstanding modals from the API and enqueue them.\n */\n async function loadOutstandingModals(): Promise<void> {\n store.setModalsLoading(true);\n\n try {\n const modals = await client.listModals();\n\n for (const modal of modals) {\n store.enqueueModal(modal);\n }\n\n store.setLastModalsSync(Date.now());\n } finally {\n store.setModalsLoading(false);\n }\n }\n\n /**\n * Find a modal in the queue by ID.\n */\n function findModal(id: string): NotifyKitNotification | undefined {\n return store.state.modalQueue.find((m) => m.id === id);\n }\n\n /**\n * Acknowledge a modal.\n */\n async function ack(id: string): Promise<void> {\n const modal = findModal(id);\n if (modal === undefined) {\n return;\n }\n\n // Optimistically remove from queue\n store.dequeueModal(id);\n\n try {\n await client.ackModal(id);\n } catch (error) {\n // Re-enqueue on failure\n store.enqueueModal(modal);\n throw error;\n }\n }\n\n /**\n * Snooze a modal.\n */\n async function snooze(id: string, minutes: number): Promise<void> {\n const modal = findModal(id);\n if (modal === undefined) {\n return;\n }\n\n // Validate minutes against allowed options\n const allowedOptions = getSnoozeOptions(modal);\n if (!allowedOptions.includes(minutes)) {\n throw new InvalidSnoozeDurationError(minutes, allowedOptions);\n }\n\n // Optimistically remove from queue\n store.dequeueModal(id);\n\n try {\n await client.snoozeModal(id, minutes);\n } catch (error) {\n // Re-enqueue on failure\n store.enqueueModal(modal);\n throw error;\n }\n }\n\n /**\n * Acknowledge the current modal.\n */\n async function dismissCurrent(): Promise<void> {\n const current = currentModal.value;\n if (current === null) {\n return;\n }\n\n await ack(current.id);\n }\n\n /**\n * Snooze the current modal.\n */\n async function snoozeCurrent(minutes: number): Promise<void> {\n const current = currentModal.value;\n if (current === null) {\n return;\n }\n\n await snooze(current.id, minutes);\n }\n\n /**\n * Get allowed snooze options for a notification.\n */\n function getSnoozeOptions(notification: NotifyKitNotification): readonly number[] {\n return notification.modal?.snooze_options_minutes ?? [];\n }\n\n return {\n currentModal,\n modalQueue,\n hasModals,\n isLoading,\n loadOutstandingModals,\n ack,\n snooze,\n dismissCurrent,\n snoozeCurrent,\n getSnoozeOptions,\n };\n}\n"]}