@hamak/notification 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/api/index.d.ts +12 -0
  2. package/dist/api/index.d.ts.map +1 -0
  3. package/dist/api/index.js +14 -0
  4. package/dist/api/interfaces/index.d.ts +5 -0
  5. package/dist/api/interfaces/index.d.ts.map +1 -0
  6. package/dist/api/interfaces/index.js +4 -0
  7. package/dist/api/interfaces/notification-service.d.ts +150 -0
  8. package/dist/api/interfaces/notification-service.d.ts.map +1 -0
  9. package/dist/api/interfaces/notification-service.js +1 -0
  10. package/dist/api/tokens/index.d.ts +5 -0
  11. package/dist/api/tokens/index.d.ts.map +1 -0
  12. package/dist/api/tokens/index.js +4 -0
  13. package/dist/api/tokens/service-tokens.d.ts +22 -0
  14. package/dist/api/tokens/service-tokens.d.ts.map +1 -0
  15. package/dist/api/tokens/service-tokens.js +17 -0
  16. package/dist/api/types/index.d.ts +5 -0
  17. package/dist/api/types/index.d.ts.map +1 -0
  18. package/dist/api/types/index.js +4 -0
  19. package/dist/api/types/notification.d.ts +64 -0
  20. package/dist/api/types/notification.d.ts.map +1 -0
  21. package/dist/api/types/notification.js +1 -0
  22. package/dist/impl/core/index.d.ts +5 -0
  23. package/dist/impl/core/index.d.ts.map +1 -0
  24. package/dist/impl/core/index.js +4 -0
  25. package/dist/impl/core/notification-service.d.ts +75 -0
  26. package/dist/impl/core/notification-service.d.ts.map +1 -0
  27. package/dist/impl/core/notification-service.js +269 -0
  28. package/dist/impl/index.d.ts +16 -0
  29. package/dist/impl/index.d.ts.map +1 -0
  30. package/dist/impl/index.js +17 -0
  31. package/dist/impl/plugin/index.d.ts +5 -0
  32. package/dist/impl/plugin/index.d.ts.map +1 -0
  33. package/dist/impl/plugin/index.js +4 -0
  34. package/dist/impl/plugin/notification-plugin-factory.d.ts +26 -0
  35. package/dist/impl/plugin/notification-plugin-factory.d.ts.map +1 -0
  36. package/dist/impl/plugin/notification-plugin-factory.js +120 -0
  37. package/dist/impl/store/index.d.ts +6 -0
  38. package/dist/impl/store/index.d.ts.map +1 -0
  39. package/dist/impl/store/index.js +5 -0
  40. package/dist/impl/store/notification-actions.d.ts +54 -0
  41. package/dist/impl/store/notification-actions.d.ts.map +1 -0
  42. package/dist/impl/store/notification-actions.js +53 -0
  43. package/dist/impl/store/notification-reducer.d.ts +23 -0
  44. package/dist/impl/store/notification-reducer.d.ts.map +1 -0
  45. package/dist/impl/store/notification-reducer.js +47 -0
  46. package/dist/impl/utils/id-generator.d.ts +14 -0
  47. package/dist/impl/utils/id-generator.d.ts.map +1 -0
  48. package/dist/impl/utils/id-generator.js +18 -0
  49. package/dist/impl/utils/index.d.ts +5 -0
  50. package/dist/impl/utils/index.d.ts.map +1 -0
  51. package/dist/impl/utils/index.js +4 -0
  52. package/dist/index.d.ts +14 -0
  53. package/dist/index.d.ts.map +1 -0
  54. package/dist/index.js +14 -0
  55. package/dist/spi/events/index.d.ts +5 -0
  56. package/dist/spi/events/index.d.ts.map +1 -0
  57. package/dist/spi/events/index.js +4 -0
  58. package/dist/spi/events/notification-events.d.ts +38 -0
  59. package/dist/spi/events/notification-events.d.ts.map +1 -0
  60. package/dist/spi/events/notification-events.js +1 -0
  61. package/dist/spi/index.d.ts +13 -0
  62. package/dist/spi/index.d.ts.map +1 -0
  63. package/dist/spi/index.js +13 -0
  64. package/dist/spi/plugin/index.d.ts +6 -0
  65. package/dist/spi/plugin/index.d.ts.map +1 -0
  66. package/dist/spi/plugin/index.js +4 -0
  67. package/dist/spi/plugin/plugin-config.d.ts +45 -0
  68. package/dist/spi/plugin/plugin-config.d.ts.map +1 -0
  69. package/dist/spi/plugin/plugin-config.js +4 -0
  70. package/dist/spi/plugin/plugin-module.d.ts +11 -0
  71. package/dist/spi/plugin/plugin-module.d.ts.map +1 -0
  72. package/dist/spi/plugin/plugin-module.js +1 -0
  73. package/package.json +74 -0
@@ -0,0 +1,269 @@
1
+ import { generateNotificationId } from '../utils/id-generator';
2
+ /**
3
+ * Default configuration values
4
+ */
5
+ const DEFAULT_CONFIG = {
6
+ maxNotifications: 50,
7
+ defaultDuration: 5000,
8
+ position: 'top-right',
9
+ enableSound: false,
10
+ enablePersistence: false,
11
+ };
12
+ /**
13
+ * Core implementation of the notification service
14
+ */
15
+ export class NotificationService {
16
+ constructor(config, logger) {
17
+ Object.defineProperty(this, "notifications", {
18
+ enumerable: true,
19
+ configurable: true,
20
+ writable: true,
21
+ value: []
22
+ });
23
+ Object.defineProperty(this, "listeners", {
24
+ enumerable: true,
25
+ configurable: true,
26
+ writable: true,
27
+ value: new Set()
28
+ });
29
+ Object.defineProperty(this, "config", {
30
+ enumerable: true,
31
+ configurable: true,
32
+ writable: true,
33
+ value: void 0
34
+ });
35
+ Object.defineProperty(this, "logger", {
36
+ enumerable: true,
37
+ configurable: true,
38
+ writable: true,
39
+ value: void 0
40
+ });
41
+ Object.defineProperty(this, "timers", {
42
+ enumerable: true,
43
+ configurable: true,
44
+ writable: true,
45
+ value: new Map()
46
+ });
47
+ this.config = {
48
+ ...DEFAULT_CONFIG,
49
+ persistenceKey: 'hamak:notifications',
50
+ ...config,
51
+ };
52
+ this.logger = logger;
53
+ // Load persisted notifications if enabled
54
+ if (this.config.enablePersistence) {
55
+ this.loadFromStorage();
56
+ }
57
+ this.logger.debug('NotificationService initialized', {
58
+ config: this.config,
59
+ });
60
+ }
61
+ /**
62
+ * Create a notification with full control
63
+ */
64
+ notify(notification) {
65
+ const id = generateNotificationId();
66
+ const timestamp = Date.now();
67
+ const fullNotification = {
68
+ id,
69
+ timestamp,
70
+ duration: notification.duration ?? this.config.defaultDuration,
71
+ ...notification,
72
+ };
73
+ // Add to notifications list
74
+ this.notifications.unshift(fullNotification);
75
+ // Enforce max notifications limit
76
+ if (this.notifications.length > this.config.maxNotifications) {
77
+ const removed = this.notifications.splice(this.config.maxNotifications);
78
+ removed.forEach((n) => this.clearTimer(n.id));
79
+ }
80
+ // Setup auto-dismiss timer if duration is set
81
+ if (fullNotification.duration && fullNotification.duration > 0) {
82
+ this.setupAutoDismiss(id, fullNotification.duration);
83
+ }
84
+ // Persist if enabled
85
+ if (this.config.enablePersistence) {
86
+ this.saveToStorage();
87
+ }
88
+ // Notify listeners
89
+ this.notifyListeners();
90
+ this.logger.debug('Notification created', {
91
+ id,
92
+ type: fullNotification.type,
93
+ title: fullNotification.title,
94
+ source: fullNotification.source,
95
+ });
96
+ return id;
97
+ }
98
+ /**
99
+ * Create an info notification
100
+ */
101
+ info(message, title = 'Info', options) {
102
+ return this.notify({
103
+ type: 'info',
104
+ title,
105
+ message,
106
+ ...options,
107
+ });
108
+ }
109
+ /**
110
+ * Create a success notification
111
+ */
112
+ success(message, title = 'Success', options) {
113
+ return this.notify({
114
+ type: 'success',
115
+ title,
116
+ message,
117
+ ...options,
118
+ });
119
+ }
120
+ /**
121
+ * Create a warning notification
122
+ */
123
+ warning(message, title = 'Warning', options) {
124
+ return this.notify({
125
+ type: 'warning',
126
+ title,
127
+ message,
128
+ ...options,
129
+ });
130
+ }
131
+ /**
132
+ * Create an error notification
133
+ */
134
+ error(message, title = 'Error', options) {
135
+ return this.notify({
136
+ type: 'error',
137
+ title,
138
+ message,
139
+ duration: 0, // Errors don't auto-dismiss by default
140
+ ...options,
141
+ });
142
+ }
143
+ /**
144
+ * Dismiss a specific notification
145
+ */
146
+ dismiss(id) {
147
+ const index = this.notifications.findIndex((n) => n.id === id);
148
+ if (index !== -1) {
149
+ this.notifications.splice(index, 1);
150
+ this.clearTimer(id);
151
+ if (this.config.enablePersistence) {
152
+ this.saveToStorage();
153
+ }
154
+ this.notifyListeners();
155
+ this.logger.debug('Notification dismissed', { id });
156
+ }
157
+ }
158
+ /**
159
+ * Dismiss all notifications
160
+ */
161
+ dismissAll() {
162
+ const count = this.notifications.length;
163
+ this.notifications = [];
164
+ // Clear all timers
165
+ this.timers.forEach((timer) => clearTimeout(timer));
166
+ this.timers.clear();
167
+ if (this.config.enablePersistence) {
168
+ this.saveToStorage();
169
+ }
170
+ this.notifyListeners();
171
+ this.logger.debug('All notifications dismissed', { count });
172
+ }
173
+ /**
174
+ * Get all current notifications
175
+ */
176
+ getAll() {
177
+ return [...this.notifications];
178
+ }
179
+ /**
180
+ * Subscribe to notification changes
181
+ */
182
+ subscribe(listener) {
183
+ this.listeners.add(listener);
184
+ this.logger.debug('Listener subscribed', { listenerCount: this.listeners.size });
185
+ // Return unsubscribe function
186
+ return () => {
187
+ this.listeners.delete(listener);
188
+ this.logger.debug('Listener unsubscribed', { listenerCount: this.listeners.size });
189
+ };
190
+ }
191
+ /**
192
+ * Cleanup resources
193
+ */
194
+ destroy() {
195
+ this.timers.forEach((timer) => clearTimeout(timer));
196
+ this.timers.clear();
197
+ this.listeners.clear();
198
+ this.notifications = [];
199
+ this.logger.debug('NotificationService destroyed');
200
+ }
201
+ /**
202
+ * Setup auto-dismiss timer for a notification
203
+ */
204
+ setupAutoDismiss(id, duration) {
205
+ const timer = setTimeout(() => {
206
+ this.dismiss(id);
207
+ }, duration);
208
+ this.timers.set(id, timer);
209
+ }
210
+ /**
211
+ * Clear timer for a notification
212
+ */
213
+ clearTimer(id) {
214
+ const timer = this.timers.get(id);
215
+ if (timer) {
216
+ clearTimeout(timer);
217
+ this.timers.delete(id);
218
+ }
219
+ }
220
+ /**
221
+ * Notify all listeners of changes
222
+ */
223
+ notifyListeners() {
224
+ const notifications = this.getAll();
225
+ this.listeners.forEach((listener) => {
226
+ try {
227
+ listener(notifications);
228
+ }
229
+ catch (error) {
230
+ this.logger.error('Error in notification listener', error instanceof Error ? error : new Error(String(error)));
231
+ }
232
+ });
233
+ }
234
+ /**
235
+ * Save notifications to localStorage
236
+ */
237
+ saveToStorage() {
238
+ if (typeof localStorage === 'undefined')
239
+ return;
240
+ try {
241
+ localStorage.setItem(this.config.persistenceKey, JSON.stringify(this.notifications));
242
+ }
243
+ catch (error) {
244
+ this.logger.warn('Failed to persist notifications', { message: error instanceof Error ? error.message : String(error) });
245
+ }
246
+ }
247
+ /**
248
+ * Load notifications from localStorage
249
+ */
250
+ loadFromStorage() {
251
+ if (typeof localStorage === 'undefined')
252
+ return;
253
+ try {
254
+ const stored = localStorage.getItem(this.config.persistenceKey);
255
+ if (stored) {
256
+ const notifications = JSON.parse(stored);
257
+ // Only restore recent notifications (within last hour)
258
+ const oneHourAgo = Date.now() - 60 * 60 * 1000;
259
+ this.notifications = notifications.filter((n) => n.timestamp > oneHourAgo);
260
+ this.logger.debug('Notifications loaded from storage', {
261
+ count: this.notifications.length,
262
+ });
263
+ }
264
+ }
265
+ catch (error) {
266
+ this.logger.warn('Failed to load persisted notifications', { message: error instanceof Error ? error.message : String(error) });
267
+ }
268
+ }
269
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @hamak/notification (impl)
3
+ *
4
+ * Core implementation of the notification system.
5
+ * Provides NotificationService, plugin factory, and Redux integration.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export * from './core/index';
10
+ export * from './plugin/index';
11
+ export * from './store/index';
12
+ export * from './utils/index';
13
+ export type { INotification, INotificationService, NotificationType, NotificationOptions, NotificationListener, } from '../api/index';
14
+ export { NOTIFICATION_SERVICE_TOKEN } from '../api/index';
15
+ export type { NotificationPluginConfig, NotificationPosition, NotificationPluginModule, NotificationEvents, } from '../spi/index';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/impl/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,cAAc,cAAc,CAAC;AAG7B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,eAAe,CAAC;AAG9B,cAAc,eAAe,CAAC;AAG9B,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAG1D,YAAY,EACV,wBAAwB,EACxB,oBAAoB,EACpB,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,cAAc,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @hamak/notification (impl)
3
+ *
4
+ * Core implementation of the notification system.
5
+ * Provides NotificationService, plugin factory, and Redux integration.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ // Export core implementation
10
+ export * from './core/index';
11
+ // Export plugin factory
12
+ export * from './plugin/index';
13
+ // Export store integration
14
+ export * from './store/index';
15
+ // Export utilities
16
+ export * from './utils/index';
17
+ export { NOTIFICATION_SERVICE_TOKEN } from '../api/index';
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Plugin factory for notification system
3
+ */
4
+ export { createNotificationPlugin } from './notification-plugin-factory';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/impl/plugin/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Plugin factory for notification system
3
+ */
4
+ export { createNotificationPlugin } from './notification-plugin-factory';
@@ -0,0 +1,26 @@
1
+ import type { PluginModule } from '@hamak/microkernel-spi';
2
+ import type { NotificationPluginConfig } from '../../spi/index';
3
+ /**
4
+ * Create a notification plugin for the microkernel
5
+ *
6
+ * @param config - Configuration options for the notification plugin
7
+ * @returns A plugin module ready to be registered with the host
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { createNotificationPlugin } from '@hamak/notification-impl';
12
+ *
13
+ * const notificationPlugin = createNotificationPlugin({
14
+ * maxNotifications: 100,
15
+ * defaultDuration: 3000,
16
+ * position: 'top-right',
17
+ * enablePersistence: true
18
+ * });
19
+ *
20
+ * const host = new Host();
21
+ * host.registerPlugin('notification', manifest, notificationPlugin);
22
+ * await host.bootstrapAllAtRoot();
23
+ * ```
24
+ */
25
+ export declare function createNotificationPlugin(config?: NotificationPluginConfig): PluginModule;
26
+ //# sourceMappingURL=notification-plugin-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification-plugin-factory.d.ts","sourceRoot":"","sources":["../../../src/impl/plugin/notification-plugin-factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAyB,MAAM,wBAAwB,CAAC;AAIlF,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAMhE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,GAAE,wBAA6B,GACpC,YAAY,CAiHd"}
@@ -0,0 +1,120 @@
1
+ import { LOG_MANAGER_TOKEN } from '@hamak/logging/api';
2
+ import { NOTIFICATION_SERVICE_TOKEN } from '../../api/index';
3
+ import { NotificationService } from '../core/notification-service';
4
+ import { notificationReducer } from '../store/notification-reducer';
5
+ /**
6
+ * Create a notification plugin for the microkernel
7
+ *
8
+ * @param config - Configuration options for the notification plugin
9
+ * @returns A plugin module ready to be registered with the host
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * import { createNotificationPlugin } from '@hamak/notification-impl';
14
+ *
15
+ * const notificationPlugin = createNotificationPlugin({
16
+ * maxNotifications: 100,
17
+ * defaultDuration: 3000,
18
+ * position: 'top-right',
19
+ * enablePersistence: true
20
+ * });
21
+ *
22
+ * const host = new Host();
23
+ * host.registerPlugin('notification', manifest, notificationPlugin);
24
+ * await host.bootstrapAllAtRoot();
25
+ * ```
26
+ */
27
+ export function createNotificationPlugin(config = {}) {
28
+ let notificationService;
29
+ let logger;
30
+ return {
31
+ async initialize(ctx) {
32
+ // Resolve logger
33
+ const logManager = ctx.resolve(LOG_MANAGER_TOKEN);
34
+ logger = logManager.createLogger({ plugin: 'notification', module: 'plugin' });
35
+ // Create notification service
36
+ notificationService = new NotificationService(config, logger);
37
+ // Register service in DI container
38
+ ctx.provide({ provide: NOTIFICATION_SERVICE_TOKEN, useValue: notificationService });
39
+ // Register store reducer if ui-store is available
40
+ try {
41
+ // Try to resolve STORE_EXTENSIONS_TOKEN (optional dependency)
42
+ const STORE_EXTENSIONS_TOKEN = Symbol.for('@hamak/ui-store:StoreExtensionsRegistry');
43
+ const storeExtensions = ctx.resolve(STORE_EXTENSIONS_TOKEN);
44
+ if (storeExtensions && typeof storeExtensions.register === 'function') {
45
+ storeExtensions.register('notification', {
46
+ reducers: {
47
+ notifications: notificationReducer,
48
+ },
49
+ });
50
+ logger.debug('Notification reducer registered with store');
51
+ }
52
+ }
53
+ catch (error) {
54
+ logger.debug('Store not available, skipping reducer registration', { message: error instanceof Error ? error.message : String(error) });
55
+ }
56
+ // Register commands
57
+ ctx.commands.register('notification.show', (args) => {
58
+ const { type = 'info', message, title, ...options } = args;
59
+ return notificationService.notify({ type, message, title, ...options });
60
+ });
61
+ ctx.commands.register('notification.info', (args) => {
62
+ const { message, title, ...options } = args;
63
+ return notificationService.info(message, title, options);
64
+ });
65
+ ctx.commands.register('notification.success', (args) => {
66
+ const { message, title, ...options } = args;
67
+ return notificationService.success(message, title, options);
68
+ });
69
+ ctx.commands.register('notification.warning', (args) => {
70
+ const { message, title, ...options } = args;
71
+ return notificationService.warning(message, title, options);
72
+ });
73
+ ctx.commands.register('notification.error', (args) => {
74
+ const { message, title, ...options } = args;
75
+ return notificationService.error(message, title, options);
76
+ });
77
+ ctx.commands.register('notification.dismiss', (args) => {
78
+ const { id } = args;
79
+ notificationService.dismiss(id);
80
+ });
81
+ ctx.commands.register('notification.dismissAll', () => {
82
+ notificationService.dismissAll();
83
+ });
84
+ logger.info('Notification plugin initialized', {
85
+ maxNotifications: config.maxNotifications,
86
+ defaultDuration: config.defaultDuration,
87
+ position: config.position,
88
+ enablePersistence: config.enablePersistence,
89
+ });
90
+ },
91
+ async activate(ctx) {
92
+ // Resolve the notification service
93
+ const service = ctx.resolve(NOTIFICATION_SERVICE_TOKEN);
94
+ // Setup hook listeners for cross-plugin notifications
95
+ ctx.hooks.on('notification:show', (data) => {
96
+ service.notify(data);
97
+ logger.debug('Notification shown via hook', { data });
98
+ });
99
+ // Emit ready event
100
+ ctx.hooks.emit('notification:ready', { service });
101
+ logger.info('Notification plugin activated');
102
+ // Show a welcome notification if in debug mode
103
+ if (config.maxNotifications !== undefined) {
104
+ service.info('Notification system ready', 'System', {
105
+ duration: 3000,
106
+ source: 'notification-plugin',
107
+ metadata: { plugin: 'notification' },
108
+ });
109
+ }
110
+ },
111
+ async deactivate() {
112
+ logger.info('Notification plugin deactivating');
113
+ // Cleanup
114
+ if (notificationService) {
115
+ notificationService.destroy();
116
+ }
117
+ logger.info('Notification plugin deactivated');
118
+ },
119
+ };
120
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Redux store integration
3
+ */
4
+ export { notificationReducer, type NotificationState } from './notification-reducer';
5
+ export { NOTIFICATION_ACTIONS, addNotification, dismissNotification, dismissAllNotifications, markNotificationsRead, setAllNotifications, type NotificationAction, } from './notification-actions';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/impl/store/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,EACrB,mBAAmB,EACnB,KAAK,kBAAkB,GACxB,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Redux store integration
3
+ */
4
+ export { notificationReducer } from './notification-reducer';
5
+ export { NOTIFICATION_ACTIONS, addNotification, dismissNotification, dismissAllNotifications, markNotificationsRead, setAllNotifications, } from './notification-actions';
@@ -0,0 +1,54 @@
1
+ import type { INotification } from '../../api/index';
2
+ /**
3
+ * Redux action types for notification state management
4
+ */
5
+ export declare const NOTIFICATION_ACTIONS: {
6
+ readonly ADD: "notification/add";
7
+ readonly DISMISS: "notification/dismiss";
8
+ readonly DISMISS_ALL: "notification/dismissAll";
9
+ readonly MARK_READ: "notification/markRead";
10
+ readonly SET_ALL: "notification/setAll";
11
+ };
12
+ /**
13
+ * Action creators for notification state
14
+ */
15
+ export interface NotificationAddAction {
16
+ type: typeof NOTIFICATION_ACTIONS.ADD;
17
+ payload: INotification;
18
+ }
19
+ export interface NotificationDismissAction {
20
+ type: typeof NOTIFICATION_ACTIONS.DISMISS;
21
+ payload: string;
22
+ }
23
+ export interface NotificationDismissAllAction {
24
+ type: typeof NOTIFICATION_ACTIONS.DISMISS_ALL;
25
+ }
26
+ export interface NotificationMarkReadAction {
27
+ type: typeof NOTIFICATION_ACTIONS.MARK_READ;
28
+ }
29
+ export interface NotificationSetAllAction {
30
+ type: typeof NOTIFICATION_ACTIONS.SET_ALL;
31
+ payload: INotification[];
32
+ }
33
+ export type NotificationAction = NotificationAddAction | NotificationDismissAction | NotificationDismissAllAction | NotificationMarkReadAction | NotificationSetAllAction;
34
+ /**
35
+ * Add a notification
36
+ */
37
+ export declare function addNotification(notification: INotification): NotificationAddAction;
38
+ /**
39
+ * Dismiss a notification by ID
40
+ */
41
+ export declare function dismissNotification(id: string): NotificationDismissAction;
42
+ /**
43
+ * Dismiss all notifications
44
+ */
45
+ export declare function dismissAllNotifications(): NotificationDismissAllAction;
46
+ /**
47
+ * Mark all notifications as read
48
+ */
49
+ export declare function markNotificationsRead(): NotificationMarkReadAction;
50
+ /**
51
+ * Set all notifications (used for syncing with service)
52
+ */
53
+ export declare function setAllNotifications(notifications: INotification[]): NotificationSetAllAction;
54
+ //# sourceMappingURL=notification-actions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification-actions.d.ts","sourceRoot":"","sources":["../../../src/impl/store/notification-actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;;;;CAMvB,CAAC;AAEX;;GAEG;AAEH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,OAAO,oBAAoB,CAAC,GAAG,CAAC;IACtC,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,OAAO,oBAAoB,CAAC,OAAO,CAAC;IAC1C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,OAAO,oBAAoB,CAAC,WAAW,CAAC;CAC/C;AAED,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,OAAO,oBAAoB,CAAC,SAAS,CAAC;CAC7C;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,OAAO,oBAAoB,CAAC,OAAO,CAAC;IAC1C,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,MAAM,MAAM,kBAAkB,GAC1B,qBAAqB,GACrB,yBAAyB,GACzB,4BAA4B,GAC5B,0BAA0B,GAC1B,wBAAwB,CAAC;AAE7B;;GAEG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,aAAa,GAAG,qBAAqB,CAKlF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,yBAAyB,CAKzE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,4BAA4B,CAItE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,0BAA0B,CAIlE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,aAAa,EAAE,GAAG,wBAAwB,CAK5F"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Redux action types for notification state management
3
+ */
4
+ export const NOTIFICATION_ACTIONS = {
5
+ ADD: 'notification/add',
6
+ DISMISS: 'notification/dismiss',
7
+ DISMISS_ALL: 'notification/dismissAll',
8
+ MARK_READ: 'notification/markRead',
9
+ SET_ALL: 'notification/setAll',
10
+ };
11
+ /**
12
+ * Add a notification
13
+ */
14
+ export function addNotification(notification) {
15
+ return {
16
+ type: NOTIFICATION_ACTIONS.ADD,
17
+ payload: notification,
18
+ };
19
+ }
20
+ /**
21
+ * Dismiss a notification by ID
22
+ */
23
+ export function dismissNotification(id) {
24
+ return {
25
+ type: NOTIFICATION_ACTIONS.DISMISS,
26
+ payload: id,
27
+ };
28
+ }
29
+ /**
30
+ * Dismiss all notifications
31
+ */
32
+ export function dismissAllNotifications() {
33
+ return {
34
+ type: NOTIFICATION_ACTIONS.DISMISS_ALL,
35
+ };
36
+ }
37
+ /**
38
+ * Mark all notifications as read
39
+ */
40
+ export function markNotificationsRead() {
41
+ return {
42
+ type: NOTIFICATION_ACTIONS.MARK_READ,
43
+ };
44
+ }
45
+ /**
46
+ * Set all notifications (used for syncing with service)
47
+ */
48
+ export function setAllNotifications(notifications) {
49
+ return {
50
+ type: NOTIFICATION_ACTIONS.SET_ALL,
51
+ payload: notifications,
52
+ };
53
+ }
@@ -0,0 +1,23 @@
1
+ import type { INotification } from '../../api/index';
2
+ import { type NotificationAction } from './notification-actions';
3
+ /**
4
+ * State shape for notifications in Redux store
5
+ */
6
+ export interface NotificationState {
7
+ /**
8
+ * All active notifications
9
+ */
10
+ items: INotification[];
11
+ /**
12
+ * Count of unread notifications
13
+ */
14
+ unreadCount: number;
15
+ }
16
+ /**
17
+ * Notification reducer
18
+ *
19
+ * This reducer manages notification state in Redux.
20
+ * It should be kept in sync with the NotificationService via subscriptions.
21
+ */
22
+ export declare function notificationReducer(state: NotificationState | undefined, action: NotificationAction): NotificationState;
23
+ //# sourceMappingURL=notification-reducer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification-reducer.d.ts","sourceRoot":"","sources":["../../../src/impl/store/notification-reducer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAwB,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEvF;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,KAAK,EAAE,aAAa,EAAE,CAAC;IAEvB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAUD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,iBAAiB,YAAe,EACvC,MAAM,EAAE,kBAAkB,GACzB,iBAAiB,CAqCnB"}
@@ -0,0 +1,47 @@
1
+ import { NOTIFICATION_ACTIONS } from './notification-actions';
2
+ /**
3
+ * Initial state
4
+ */
5
+ const initialState = {
6
+ items: [],
7
+ unreadCount: 0,
8
+ };
9
+ /**
10
+ * Notification reducer
11
+ *
12
+ * This reducer manages notification state in Redux.
13
+ * It should be kept in sync with the NotificationService via subscriptions.
14
+ */
15
+ export function notificationReducer(state = initialState, action) {
16
+ switch (action.type) {
17
+ case NOTIFICATION_ACTIONS.ADD:
18
+ return {
19
+ ...state,
20
+ items: [action.payload, ...state.items],
21
+ unreadCount: state.unreadCount + 1,
22
+ };
23
+ case NOTIFICATION_ACTIONS.DISMISS:
24
+ return {
25
+ ...state,
26
+ items: state.items.filter((n) => n.id !== action.payload),
27
+ };
28
+ case NOTIFICATION_ACTIONS.DISMISS_ALL:
29
+ return {
30
+ ...state,
31
+ items: [],
32
+ unreadCount: 0,
33
+ };
34
+ case NOTIFICATION_ACTIONS.MARK_READ:
35
+ return {
36
+ ...state,
37
+ unreadCount: 0,
38
+ };
39
+ case NOTIFICATION_ACTIONS.SET_ALL:
40
+ return {
41
+ ...state,
42
+ items: action.payload,
43
+ };
44
+ default:
45
+ return state;
46
+ }
47
+ }