@codingfactory/notify-kit-client 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-7LQBNDRD.js +235 -0
- package/dist/chunk-7LQBNDRD.js.map +1 -0
- package/dist/index.d.ts +547 -0
- package/dist/index.js +737 -0
- package/dist/index.js.map +1 -0
- package/dist/nuxt/index.d.ts +114 -0
- package/dist/nuxt/index.js +55 -0
- package/dist/nuxt/index.js.map +1 -0
- package/dist/useNotifyKitModals-BZ_NiTKw.d.ts +586 -0
- package/package.json +77 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { provide, computed, reactive, readonly } from 'vue';
|
|
2
|
+
|
|
3
|
+
// src/composables/useNotifyKitStore.ts
|
|
4
|
+
var NOTIFY_KIT_STORE_KEY = /* @__PURE__ */ Symbol("notify-kit-store");
|
|
5
|
+
function createInitialState() {
|
|
6
|
+
return {
|
|
7
|
+
notifications: [],
|
|
8
|
+
notificationsLoading: false,
|
|
9
|
+
notificationsMeta: null,
|
|
10
|
+
unreadCount: 0,
|
|
11
|
+
unreadCountLoading: false,
|
|
12
|
+
modalQueue: [],
|
|
13
|
+
modalsLoading: false,
|
|
14
|
+
broadcastChannel: null,
|
|
15
|
+
connectionState: "disconnected",
|
|
16
|
+
lastNotificationsSync: null,
|
|
17
|
+
lastModalsSync: null
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
var storeState = null;
|
|
21
|
+
function getStoreState() {
|
|
22
|
+
storeState ??= reactive(createInitialState());
|
|
23
|
+
return storeState;
|
|
24
|
+
}
|
|
25
|
+
function resetNotifyKitStore() {
|
|
26
|
+
if (storeState !== null) {
|
|
27
|
+
Object.assign(storeState, createInitialState());
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function createStoreReturn(state) {
|
|
31
|
+
const hasUnread = computed(() => state.unreadCount > 0);
|
|
32
|
+
const currentModal = computed(() => state.modalQueue[0] ?? null);
|
|
33
|
+
const hasModals = computed(() => state.modalQueue.length > 0);
|
|
34
|
+
return {
|
|
35
|
+
// State as readonly
|
|
36
|
+
state: readonly(state),
|
|
37
|
+
// Computed
|
|
38
|
+
hasUnread,
|
|
39
|
+
currentModal,
|
|
40
|
+
hasModals,
|
|
41
|
+
// Notification mutations
|
|
42
|
+
addNotification: (notification) => {
|
|
43
|
+
state.notifications.unshift(notification);
|
|
44
|
+
},
|
|
45
|
+
setNotifications: (notifications) => {
|
|
46
|
+
state.notifications = [...notifications];
|
|
47
|
+
},
|
|
48
|
+
markNotificationRead: (id) => {
|
|
49
|
+
const index = state.notifications.findIndex((n) => n.id === id);
|
|
50
|
+
if (index !== -1) {
|
|
51
|
+
const notification = state.notifications[index];
|
|
52
|
+
if (notification !== void 0) {
|
|
53
|
+
state.notifications[index] = {
|
|
54
|
+
...notification,
|
|
55
|
+
read_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
removeNotification: (id) => {
|
|
61
|
+
const index = state.notifications.findIndex((n) => n.id === id);
|
|
62
|
+
if (index !== -1) {
|
|
63
|
+
state.notifications.splice(index, 1);
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
// Unread count mutations
|
|
67
|
+
setUnreadCount: (count) => {
|
|
68
|
+
state.unreadCount = count;
|
|
69
|
+
},
|
|
70
|
+
incrementUnreadCount: () => {
|
|
71
|
+
state.unreadCount += 1;
|
|
72
|
+
},
|
|
73
|
+
decrementUnreadCount: () => {
|
|
74
|
+
if (state.unreadCount > 0) {
|
|
75
|
+
state.unreadCount -= 1;
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
// Modal queue mutations
|
|
79
|
+
enqueueModal: (notification) => {
|
|
80
|
+
const exists = state.modalQueue.some((m) => m.id === notification.id);
|
|
81
|
+
if (!exists) {
|
|
82
|
+
state.modalQueue.push(notification);
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
dequeueModal: (id) => {
|
|
86
|
+
const index = state.modalQueue.findIndex((m) => m.id === id);
|
|
87
|
+
if (index !== -1) {
|
|
88
|
+
state.modalQueue.splice(index, 1);
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
clearModalQueue: () => {
|
|
92
|
+
state.modalQueue = [];
|
|
93
|
+
},
|
|
94
|
+
// Connection mutations
|
|
95
|
+
setConnectionState: (connectionState) => {
|
|
96
|
+
state.connectionState = connectionState;
|
|
97
|
+
},
|
|
98
|
+
setBroadcastChannel: (channel) => {
|
|
99
|
+
state.broadcastChannel = channel;
|
|
100
|
+
},
|
|
101
|
+
// Loading state mutations
|
|
102
|
+
setNotificationsLoading: (loading) => {
|
|
103
|
+
state.notificationsLoading = loading;
|
|
104
|
+
},
|
|
105
|
+
setUnreadCountLoading: (loading) => {
|
|
106
|
+
state.unreadCountLoading = loading;
|
|
107
|
+
},
|
|
108
|
+
setModalsLoading: (loading) => {
|
|
109
|
+
state.modalsLoading = loading;
|
|
110
|
+
},
|
|
111
|
+
// Meta mutations
|
|
112
|
+
setNotificationsMeta: (meta) => {
|
|
113
|
+
state.notificationsMeta = meta;
|
|
114
|
+
},
|
|
115
|
+
// Sync timestamp mutations
|
|
116
|
+
setLastNotificationsSync: (timestamp) => {
|
|
117
|
+
state.lastNotificationsSync = timestamp;
|
|
118
|
+
},
|
|
119
|
+
setLastModalsSync: (timestamp) => {
|
|
120
|
+
state.lastModalsSync = timestamp;
|
|
121
|
+
},
|
|
122
|
+
// Reset
|
|
123
|
+
reset: () => {
|
|
124
|
+
Object.assign(state, createInitialState());
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function provideNotifyKitStore() {
|
|
129
|
+
const state = getStoreState();
|
|
130
|
+
const store = createStoreReturn(state);
|
|
131
|
+
provide(NOTIFY_KIT_STORE_KEY, store);
|
|
132
|
+
return store;
|
|
133
|
+
}
|
|
134
|
+
function useNotifyKitStore() {
|
|
135
|
+
const state = getStoreState();
|
|
136
|
+
return createStoreReturn(state);
|
|
137
|
+
}
|
|
138
|
+
var InvalidSnoozeDurationError = class extends Error {
|
|
139
|
+
name = "InvalidSnoozeDurationError";
|
|
140
|
+
constructor(minutes, allowedMinutes) {
|
|
141
|
+
super(`Invalid snooze duration: ${String(minutes)}. Allowed values: ${allowedMinutes.join(", ")}`);
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
var NOTIFY_KIT_MODALS_KEY = /* @__PURE__ */ Symbol("notify-kit-modals");
|
|
145
|
+
function provideNotifyKitModals(options) {
|
|
146
|
+
const modals = useNotifyKitModals(options);
|
|
147
|
+
provide(NOTIFY_KIT_MODALS_KEY, modals);
|
|
148
|
+
return modals;
|
|
149
|
+
}
|
|
150
|
+
function useNotifyKitModals(options) {
|
|
151
|
+
const { client } = options;
|
|
152
|
+
const store = useNotifyKitStore();
|
|
153
|
+
const currentModal = computed(() => store.currentModal.value);
|
|
154
|
+
const modalQueue = computed(() => store.state.modalQueue);
|
|
155
|
+
const hasModals = computed(() => store.hasModals.value);
|
|
156
|
+
const isLoading = computed(() => store.state.modalsLoading);
|
|
157
|
+
async function loadOutstandingModals() {
|
|
158
|
+
store.setModalsLoading(true);
|
|
159
|
+
try {
|
|
160
|
+
const modals = await client.listModals();
|
|
161
|
+
for (const modal of modals) {
|
|
162
|
+
store.enqueueModal(modal);
|
|
163
|
+
}
|
|
164
|
+
store.setLastModalsSync(Date.now());
|
|
165
|
+
} finally {
|
|
166
|
+
store.setModalsLoading(false);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function findModal(id) {
|
|
170
|
+
return store.state.modalQueue.find((m) => m.id === id);
|
|
171
|
+
}
|
|
172
|
+
async function ack(id) {
|
|
173
|
+
const modal = findModal(id);
|
|
174
|
+
if (modal === void 0) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
store.dequeueModal(id);
|
|
178
|
+
try {
|
|
179
|
+
await client.ackModal(id);
|
|
180
|
+
} catch (error) {
|
|
181
|
+
store.enqueueModal(modal);
|
|
182
|
+
throw error;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
async function snooze(id, minutes) {
|
|
186
|
+
const modal = findModal(id);
|
|
187
|
+
if (modal === void 0) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const allowedOptions = getSnoozeOptions(modal);
|
|
191
|
+
if (!allowedOptions.includes(minutes)) {
|
|
192
|
+
throw new InvalidSnoozeDurationError(minutes, allowedOptions);
|
|
193
|
+
}
|
|
194
|
+
store.dequeueModal(id);
|
|
195
|
+
try {
|
|
196
|
+
await client.snoozeModal(id, minutes);
|
|
197
|
+
} catch (error) {
|
|
198
|
+
store.enqueueModal(modal);
|
|
199
|
+
throw error;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
async function dismissCurrent() {
|
|
203
|
+
const current = currentModal.value;
|
|
204
|
+
if (current === null) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
await ack(current.id);
|
|
208
|
+
}
|
|
209
|
+
async function snoozeCurrent(minutes) {
|
|
210
|
+
const current = currentModal.value;
|
|
211
|
+
if (current === null) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
await snooze(current.id, minutes);
|
|
215
|
+
}
|
|
216
|
+
function getSnoozeOptions(notification) {
|
|
217
|
+
return notification.modal?.snooze_options_minutes ?? [];
|
|
218
|
+
}
|
|
219
|
+
return {
|
|
220
|
+
currentModal,
|
|
221
|
+
modalQueue,
|
|
222
|
+
hasModals,
|
|
223
|
+
isLoading,
|
|
224
|
+
loadOutstandingModals,
|
|
225
|
+
ack,
|
|
226
|
+
snooze,
|
|
227
|
+
dismissCurrent,
|
|
228
|
+
snoozeCurrent,
|
|
229
|
+
getSnoozeOptions
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
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
|
|
@@ -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-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"]}
|