Skip to content

Instantly share code, notes, and snippets.

@dovranJorayev
Last active October 2, 2024 12:10
Show Gist options
  • Save dovranJorayev/801cfa544f355705c54516e70ebbab37 to your computer and use it in GitHub Desktop.
Save dovranJorayev/801cfa544f355705c54516e70ebbab37 to your computer and use it in GitHub Desktop.
Proof of concept app notification service implementation
// shared/lib/notifications/core.ts //////////////////////////////////////////////
import {
NotificationData,
NotificationsStore,
cleanNotifications,
cleanNotificationsQueue,
hideNotification,
showNotification,
updateNotification,
updateNotificationsState,
} from '@mantine/notifications';
export { createNotificationsStore } from '@mantine/notifications';
export NotificationService = ReturnType<typeof createNotificationsService>;
export function createNotificationsService(store: NotificationsStore) {
return {
show: (notification: NotificationData) => showNotification(notification, store),
hide: (id: string) => hideNotification(id, store),
update: (notification: NotificationData) => updateNotification(notification, store),
clean: () => cleanNotifications(store),
cleanQueue: () => cleanNotificationsQueue(store),
updateState: (update: (notifications: NotificationData[]) => NotificationData[]) =>
updateNotificationsState(store, update),
};
}
// shared/lib/notifications/react.tsx //////////////////////////////////////////////
import {
Notifications,
NotificationsProps,
NotificationsStore,
} from '@mantine/notifications';
export type NotificationsProviderProps = Omit<NotificationsProps, 'store'> & {
store: NotificationsStore;
children: React.ReactNode;
};
export const NotificationsProvider: React.FC<NotificationsProviderProps> = ({
store,
children,
...props
}) => {
return (
<>
<Notifications store={store} {...props} />
{children}
</>
);
};
// shared/config/ctx.ts //////////////////////////////////////////////
const $notificationStore = createStore<NotificationStore | null>(null);
const $notificationService = createStore<NotificationService | null>(null);
export const ctx = {
$notificationStore: readonly($notificationStore) as Store<NotificationStore>,
$notificationService readonly($notificationService) as Store<NotificationService>,
...
/**
* @protected for app composition root & testing
* Avoid to use it in bussiness code
*/
__: {
$notificationStore,
$notificationService
}
}
// app.tsx //////////////////////////////////////////////
const notificationsStore = createNotificationsStore();
const notificationsService = new createNotificationsService(notificationsStore);
const scope = fork({
values: [
[ctx.__.$notificationStore, notificationsStore],
[ctx.__.$notificationsService, notificationsService],
]
})
ReactDOM.createRoot(container).render(
<ScopeProvider value={scope}>
<MantineProvider>
<NotificationsProvider store={notificationsStore}>
....
</NotificationsProvider>
</MantineProvider>
</ScopeProvider>
);
@dovranJorayev
Copy link
Author

dovranJorayev commented Aug 7, 2024

// features/create-some/model.ts

const create = createEvent();
const addSomeMutation = createAddSomeMutation();

.... logic 

sample(
   clock: addSomeMutation.finished.success,
   target: attach({
      source: ctx.$notificationService,
      effect: (notificationService) => {
           notificationService.show(...);
      }
   })
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment