@magicbell/react-headless
Advanced tools
Comparing version 4.5.0 to 4.5.1
/** | ||
* @license @magicbell/react-headless v4.5.0 | ||
* @license @magicbell/react-headless v4.5.1 | ||
* | ||
@@ -4,0 +4,0 @@ * Copyright (c) MagicBell Inc. and its affiliates. |
/** | ||
* @license @magicbell/react-headless v4.5.0 | ||
* @license @magicbell/react-headless v4.5.1 | ||
* | ||
@@ -96,3 +96,3 @@ * Copyright (c) MagicBell Inc. and its affiliates. | ||
name: "@magicbell/react-headless", | ||
version: "4.5.0" | ||
version: "4.5.1" | ||
} | ||
@@ -99,0 +99,0 @@ }); |
/** | ||
* @license @magicbell/react-headless v4.5.0 | ||
* @license @magicbell/react-headless v4.5.1 | ||
* | ||
@@ -10,3 +10,3 @@ * Copyright (c) MagicBell Inc. and its affiliates. | ||
"use strict";var ie=Object.defineProperty,re=Object.defineProperties;var ce=Object.getOwnPropertyDescriptors;var j=Object.getOwnPropertySymbols;var J=Object.prototype.hasOwnProperty,H=Object.prototype.propertyIsEnumerable;var T=(e,n,t)=>n in e?ie(e,n,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[n]=t,p=(e,n)=>{for(var t in n||(n={}))J.call(n,t)&&T(e,t,n[t]);if(j)for(var t of j(n))H.call(n,t)&&T(e,t,n[t]);return e},g=(e,n)=>re(e,ce(n));var q=(e,n)=>{var t={};for(var s in e)J.call(e,s)&&n.indexOf(s)<0&&(t[s]=e[s]);if(e!=null&&j)for(var s of j(e))n.indexOf(s)<0&&H.call(e,s)&&(t[s]=e[s]);return t};var $=(e,n,t)=>(T(e,typeof n!="symbol"?n+"":n,t),t);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});require("tiny-warning");const z=require("react/jsx-runtime"),y=require("react"),ae=require("magicbell/user-client"),ue=require("zustand/vanilla"),le=require("zustand"),fe=require("humps"),de=require("immer"),m=require("ramda"),he=require("mitt"),me=require("dayjs"),pe=require("dayjs/plugin/localizedFormat"),Ae=require("dayjs/plugin/relativeTime"),ge=require("dayjs/plugin/updateLocale"),x=e=>e&&typeof e=="object"&&"default"in e?e:{default:e},ye=x(ue),L=x(le),b=x(fe),P=x(de),W=x(he),I=x(me),ve=x(pe),Pe=x(Ae),we=x(ge),Ne=ye.default((e,n)=>{let t=null,s="";return{apiKey:"",userEmail:void 0,userExternalId:void 0,userKey:void 0,clientId:Math.random().toString(36).substring(2)+Date.now(),serverURL:"https://api.magicbell.com",appInfo:void 0,getClient(){const o=n(),r=JSON.stringify([o.apiKey,o.userEmail,o.userExternalId,o.userKey]);return r!==s&&(s=r,t=new ae.UserClient({userExternalId:o.userExternalId,userEmail:o.userEmail,userHmac:o.userKey,apiKey:o.apiKey,host:o.serverURL,appInfo:o.appInfo||{name:"@magicbell/react-headless",version:"4.5.0"}})),t}}}),U=Ne;function D(e,n,t,s){const o=U.getState().getClient(),r=s?Object.fromEntries(Object.entries(s).map(([c,i])=>[c,String(i)])):void 0;return o.request({method:e,path:n,data:t,params:r})}function E(e,n){return D("GET",e,void 0,n)}function S(e,n,t){return D("POST",e,n,t)}function G(e,n){return D("DELETE",e,void 0,n)}function V(e,n){return D("PUT",e,n)}class xe{constructor(n="/config"){$(this,"remotePathOrUrl");this.remotePathOrUrl=n}async get(){const n=await E(this.remotePathOrUrl);return b.default.camelizeKeys(n)}}const Se=L.default((e,n)=>({channels:void 0,inbox:void 0,ws:void 0,lastFetchedAt:void 0,_repository:new xe,fetch:async()=>{const{_repository:t}=n(),s=await t.get();e(g(p({},s),{lastFetchedAt:Date.now()}))}})),K=Se;class be{constructor(n){$(this,"remotePathOrUrl");this.remotePathOrUrl=n}async get(n){const t=`${this.remotePathOrUrl}/${n}`,s=await E(t);return b.default.camelizeKeys(s)}async findBy(n){try{const t=await E(this.remotePathOrUrl,n);return b.default.camelizeKeys(t)}catch(t){if(/Network Error/.test(t.message))return;throw t}}delete(n){const t=`${this.remotePathOrUrl}/${n}`;return G(t).then(()=>!0).catch(()=>!1)}}class X extends be{constructor(n="/notifications"){super(n)}archive(n){const t=`${this.remotePathOrUrl}/${n}/archive`;return S(t).then(()=>!0).catch(()=>!1)}unarchive(n){const t=`${this.remotePathOrUrl}/${n}/unarchive`;return S(t).then(()=>!0).catch(()=>!1)}markAsRead(n){const t=`${this.remotePathOrUrl}/${n}/read`;return S(t).then(()=>!0).catch(()=>!1)}markAsUnread(n){const t=`${this.remotePathOrUrl}/${n}/unread`;return S(t).then(()=>!0).catch(()=>!1)}markAllAsSeen(n){const t=`${this.remotePathOrUrl}/seen`;return S(t,void 0,n).then(()=>!0).catch(()=>!1)}markAllAsRead(n){const t=`${this.remotePathOrUrl}/read`;return S(t,void 0,n).then(()=>!0).catch(()=>!1)}}const Y=W.default(),F=W.default();function v(e,n,t){t==="remote"&&Y.emit(e,n),F.emit(e,{data:n,source:t})}function Ce(e){const{clientId:n}=U.getState(),t=e.name.replace(/\//gi,"."),s=e.data;return s.client_id&&s.client_id===n?Promise.resolve(!1):typeof s.id=="string"?t==="notifications.delete"?(v(t,s,"remote"),Promise.resolve(!0)):new X().get(s.id).then(c=>(v(t,c.notification,"remote"),!0)):(v(t,s,"remote"),Promise.resolve(!0))}const ke={context:{},total:0,totalPages:0,perPage:0,currentPage:1,unreadCount:0,unseenCount:0,notifications:[]};function B(e){return p(p({},ke),e)}function _e(e,n,t={reset:!1}){const c=n,{notifications:s=[]}=c,o=q(c,["notifications"]),r=t.reset?s:m.uniqBy(i=>i.id,t.prepend?[...s,...e.notifications]:[...e.notifications,...s]);return p({context:e.context,notifications:r},o)}function Ee(e,n){return e===n||e!==e&&n!==n}function Q(e){return Array.isArray(e)?e:String(e).split(",")}function w(e,n,t=Ee){const s=[];return n=p({archived:!1},n),Object.keys(n).forEach(o=>{const r=n[o];(o==="read"&&!t(!m.isNil(e.readAt),r)||o==="seen"&&!t(!m.isNil(e.seenAt),r)||o==="archived"&&!t(!m.isNil(e.archivedAt),r)||o==="categories"&&Q(r).every(c=>!t(e.category,c))||o==="topics"&&Q(r).every(c=>!t(e.topic,c))||Object.hasOwnProperty.call(e,o)&&!t(e[o],r))&&s.push(o)}),{result:s.length===0,delta:s}}function k(){return Math.floor(Date.now()/1e3)}const Ie=L.default((e,n)=>({stores:{},_repository:new X,setStore:(t,s={},o={})=>{e(P.default(r=>{r.stores[t]=B(g(p({},o),{context:s}))}))},fetchStore:async(t,s={},o={})=>{const{stores:r,_repository:c}=n(),i=r[t];if(i){const u=await c.findBy(p(p({},i.context),s));if(!u)return;e(P.default(d=>{d.stores[t]=_e(i,g(p({},u),{lastFetchedAt:new Date}),o)}))}else console.error(`Store not found. Define a store with the ${t} ID`)},fetchAllStores:async(t={},s={})=>{const{stores:o,fetchStore:r}=n(),i=Object.keys(o).map(u=>r(u,t,s));await Promise.all(i)},markNotificationAsSeen:t=>{const{stores:s}=n(),o=t.id;v("notifications.seen",t,"local"),e(P.default(r=>{for(const c in s){const{notifications:i,unseenCount:u}=s[c],d=m.findIndex(m.propEq("id",o),i);d>-1&&(i[d].seenAt||(r.stores[c].unseenCount=Math.max(0,u-1),r.stores[c].notifications[d]=m.mergeRight(i[d],{seenAt:k()})))}}))},markNotificationAsRead:t=>{const{stores:s,_repository:o}=n(),{id:r}=t,c=o.markAsRead(r);return v("notifications.read",t,"local"),e(P.default(i=>{const u=k(),d={readAt:u,seenAt:u};for(const a in s){const{total:f,notifications:l,context:h,unreadCount:A,unseenCount:O}=s[a],R=m.findIndex(m.propEq("id",r),l);if(R>-1){t.readAt||(i.stores[a].unreadCount=Math.max(0,A-1)),t.seenAt||(i.stores[a].unseenCount=Math.max(0,O-1));const C=m.mergeRight(l[R],d);w(C,h).result?i.stores[a].notifications[R]=C:(i.stores[a].total=Math.max(0,f-1),i.stores[a].notifications.splice(R,1))}else{const C=m.mergeRight(t,d);w(C,h).result&&(i.stores[a].total+=1,i.stores[a].notifications.push(C))}}})),c},markNotificationAsUnread:t=>{const{stores:s,_repository:o}=n(),{id:r}=t,c=o.markAsUnread(r);return v("notifications.unread",t,"local"),e(P.default(i=>{const u={readAt:null};for(const d in s){const{notifications:a,context:f}=s[d],l=m.findIndex(m.propEq("id",r),a);if(l>-1){const h=m.mergeRight(a[l],u);w(h,f).result?(t.readAt&&(i.stores[d].unreadCount+=1),i.stores[d].notifications[l]=h):(i.stores[d].total=Math.max(0,i.stores[d].total-1),i.stores[d].notifications.splice(l,1))}else{const h=m.mergeRight(t,u);w(h,f).result&&(i.stores[d].total+=1,t.readAt&&(i.stores[d].unreadCount+=1),i.stores[d].notifications.push(h))}}})),c},archiveNotification:(t,s={})=>{const{stores:o,_repository:r}=n(),{id:c}=t;let i=Promise.resolve(!0);return s.persist!==!1&&(i=r.archive(c),v("notifications.archived",t,"local")),e(P.default(u=>{const a={archivedAt:k()};for(const f in o){const l=o[f],h=m.findIndex(m.propEq("id",c),l.notifications);if(h>-1){const A=p(p({},l.notifications[h]),a);w(A,l.context).result?u.stores[f].notifications[h]=A:(t.readAt||(u.stores[f].unreadCount=Math.max(0,l.unreadCount-1)),t.seenAt||(u.stores[f].unseenCount=Math.max(0,l.unseenCount-1)),u.stores[f].total=Math.max(0,l.total-1),u.stores[f].notifications.splice(h,1))}else{const A=p(p({},t),a);w(A,l.context).result&&(t.readAt||(u.stores[f].unreadCount+=1),t.seenAt||(u.stores[f].unseenCount+=1),u.stores[f].total+=1,u.stores[f].notifications.push(A))}}})),i},unarchiveNotification:(t,s={})=>{const{stores:o,_repository:r}=n(),{id:c}=t;let i=Promise.resolve(!0);return s.persist!==!1&&(i=r.unarchive(c),v("notifications.unarchived",t,"local")),e(P.default(u=>{const d={archivedAt:null};for(const a in o){const f=o[a],l=m.findIndex(m.propEq("id",c),f.notifications);if(l>-1){const h=p(p({},f.notifications[l]),d);w(h,f.context).result?u.stores[a].notifications[l]=h:(t.readAt||(u.stores[a].unreadCount=Math.max(0,f.unreadCount-1)),t.seenAt||(u.stores[a].unseenCount=Math.max(0,f.unseenCount-1)),u.stores[a].total=Math.max(0,f.total-1),u.stores[a].notifications.splice(l,1))}else{const h=p(p({},t),d);w(h,f.context).result&&(t.readAt||(u.stores[a].unreadCount+=1),t.seenAt||(u.stores[a].unseenCount+=1),u.stores[a].total+=1,u.stores[a].notifications.push(h))}}})),i},deleteNotification:(t,s={})=>{const{stores:o,_repository:r}=n(),c=t.id;let i=Promise.resolve(!0);return s.persist!==!1&&(i=r.delete(c),v("notifications.delete",t,"local")),e(P.default(u=>{for(const d in o){const{notifications:a,total:f,unseenCount:l,unreadCount:h}=o[d],A=m.findIndex(m.propEq("id",c),a);if(A>-1){const O=a[A];O.seenAt||(u.stores[d].unseenCount=Math.max(0,l-1)),O.readAt||(u.stores[d].unreadCount=Math.max(0,h-1)),u.stores[d].total=Math.max(0,f-1),u.stores[d].notifications.splice(A,1)}}})),i},markAllAsSeen:(t={persist:!0,updateModels:!0})=>{var c;const{stores:s,_repository:o}=n();let r=Promise.resolve(!0);if(t.persist!==!1){const i=t.storeId?(c=s[t.storeId])==null?void 0:c.context:{};r=o.markAllAsSeen(i),v("notifications.seen.all",null,"local")}return e(P.default(i=>{const u=new Map,d=k();for(const a in s){const{context:f}=s[a];if(i.stores[a].unseenCount=0,t.updateModels!==!1){if(f.seen!==!0)for(const l of i.stores[a].notifications)l.seenAt||(l.seenAt=d,u.set(l.id,l));f.seen===!1&&(i.stores[a].notifications=[],i.stores[a].total=0)}}for(const a in s){const{context:f}=s[a];if(f.seen!==!0)continue;const l=i.stores[a].notifications;for(const h of u.values())w(h,f).result&&!l.find(A=>A.id===h.id)&&(l.push(h),i.stores[a].total+=1)}})),r},markAllAsRead:(t={persist:!0,updateModels:!0})=>{var c;const{stores:s,_repository:o}=n();let r=Promise.resolve(!0);if(t.persist!==!1){const i=t.storeId?(c=s[t.storeId])==null?void 0:c.context:{};r=o.markAllAsRead(i),v("notifications.read.all",null,"local")}return e(P.default(i=>{const u=new Map,d=k();for(const a in s){const{context:f}=s[a];if(i.stores[a].unreadCount=0,i.stores[a].unseenCount=0,t.updateModels!==!1){if(f.read!==!0)for(const l of i.stores[a].notifications)l.readAt||(l.readAt=d,l.seenAt=d,u.set(l.id,l));f.read===!1&&(i.stores[a].notifications=[],i.stores[a].total=0)}}for(const a in s){const{context:f}=s[a];if(f.read!==!0)continue;const l=i.stores[a].notifications;for(const h of u.values())w(h,f).result&&!l.find(A=>A.id===h.id)&&(l.push(h),i.stores[a].total+=1)}})),r}})),M=Ie;function N(e,n,t={source:"any"}){y.useEffect(()=>{const s=(o={})=>{t.source==="remote"&&o.source!=="remote"||t.source==="local"&&o.source!=="local"||n(o.data,o.source)};return F.on(e,s),()=>{F.off(e,s)}},[])}function Z(){const e=M(),n=U.getState(),t=n.getClient(),s=n.apiKey,o=n.userExternalId||n.userEmail,r=()=>e.fetchAllStores({page:1},{reset:!0}),c=()=>e.fetchAllStores({page:1},{prepend:!0}),i=()=>e.markAllAsSeen({persist:!1}),u=()=>e.markAllAsRead({persist:!1}),d=l=>e.deleteNotification(l,{persist:!1}),a=l=>e.archiveNotification(l,{persist:!1}),f=l=>e.unarchiveNotification(l,{persist:!1});return y.useEffect(()=>{if(!s||!o)return;const l=t.listen();return l.forEach(h=>{!h||Ce(h)}),()=>l.close()},[t,s,o]),N("reconnected",r),N("notifications.new",c,{source:"remote"}),N("notifications.seen.all",i,{source:"remote"}),N("notifications.read.all",u,{source:"remote"}),N("notifications.read",r,{source:"remote"}),N("notifications.unread",r,{source:"remote"}),N("notifications.delete",d,{source:"remote"}),N("notifications.archived",a,{source:"remote"}),N("notifications.unarchived",f,{source:"remote"}),null}function Ue(t){var s=t,{serverURL:e}=s,n=q(s,["serverURL"]);const o=n;return e&&(o.serverURL=e),U.setState(o),o}function Me(e){const n={};return e.forEach(t=>{const{defaultQueryParams:s,defaults:o={}}=t;n[t.id]=B(p({context:s},o))}),M.setState({stores:n}),n}function Oe(o){var r=o,{children:e,stores:n=[{id:"default",defaultQueryParams:{}}],disableRealtime:t}=r,s=q(r,["children","stores","disableRealtime"]);y.useState(()=>Ue(s)),y.useEffect(()=>{Me(n)},[]);const c=K();return y.useEffect(()=>{c.lastFetchedAt||c.fetch()},[c]),z.jsxs(z.Fragment,{children:[t?null:z.jsx(Z,{}),e]})}function Re(e){const n="=".repeat((4-e.length%4)%4),t=(e+n).replace(/-/g,"+").replace(/_/g,"/"),s=window.atob(t),o=new Uint8Array(s.length);for(let r=0;r<s.length;++r)o[r]=s.charCodeAt(r);return o}function ee(e){return S("/web_push_subscriptions",{web_push_subscription:{data:e}})}function je(e,n){const t=Re(n);return e.subscribe({userVisibleOnly:!0,applicationServerKey:t})}async function qe(e,n){const t=m.path(["webPush","config","vapidAuthentication","publicKey"],n.channels),s=await je(e,t);return ee(s.toJSON())}function $e(e,n,t="web.com.magicbell-notifications"){const s=window.safari.pushNotification.permission(t);return s.permission==="granted"?Promise.resolve(s):s.permission==="denied"?Promise.reject(!1):new Promise(function(o,r){window.safari.pushNotification.requestPermission(n,t,{authenticationToken:e},function(c){if(c.deviceToken){const i={endpoint:c.deviceToken,keys:{websitePushID:t},platform:"safari"};ee(i).then(u=>{o(u)}).catch(u=>{r(u)})}else{const i=new Error("Permission was denied");r(i)}})})}function Fe({children:e,serviceWorkerPath:n="/service-worker.js",skipServiceWorkerRegistration:t=!1}){const s=K(),o="safari"in window,r="PushManager"in window;return y.useEffect(()=>{t||navigator.serviceWorker.register(n)},[n,t]),e({createSubscription:async()=>{var i,u,d;if(!s)return Promise.reject(new Error("Context for MagicBell was not found"));if(o){const a=m.path(["safari","authenticationToken"],(i=s.channels)==null?void 0:i.webPush.config),f=m.path(["safari","websitePushId"],(u=s.channels)==null?void 0:u.webPush.config),l=m.path(["safari","webServiceUrl"],(d=s.channels)==null?void 0:d.webPush.config);return $e(a,l,f)}if(r)return navigator.serviceWorker.ready.then(async a=>{await qe(a.pushManager,s)})},isPushAPISupported:r})}function te(e="default"){const{stores:n,fetchStore:t,markAllAsSeen:s,markAllAsRead:o}=M(),r=K(),c=n[e],i=y.useCallback((f,l)=>t(e,f,l),[t,e]),u=y.useCallback((f={},l)=>{const h=c.currentPage+1;return t(e,g(p({},f),{page:h}),l)},[t,e,c==null?void 0:c.currentPage]);y.useEffect(()=>{!c||r.lastFetchedAt&&!c.lastFetchedAt&&i({page:1})},[r.lastFetchedAt,c,i]);const d=y.useCallback(f=>o(g(p({},f),{storeId:e})),[o,e]),a=y.useCallback(f=>s(g(p({},f),{storeId:e})),[s,e]);return c?g(p({},c),{isEmpty:c.notifications.length===0,hasNextPage:c.currentPage<c.totalPages,fetch:i,fetchNextPage:u,markAllAsSeen:a,markAllAsRead:d}):null}function De({storeId:e}={}){const n=te(e),t=()=>n&&n.unseenCount>0?n==null?void 0:n.markAllAsSeen({updateModels:!1}):Promise.resolve(!0);return n?g(p({},n),{markAllAsSeen:t}):null}I.default.extend(ve.default);I.default.extend(Pe.default);I.default.extend(we.default);function _(e){return e?ne(e*1e3):null}function ne(e){return I.default(e)}function Ke(e){return I.default(e).unix()}function Te(e){if(m.isNil(e))return null;if(typeof e=="string")try{return JSON.parse(e)}catch(n){}return e}function se(e){const{markNotificationAsRead:n,markNotificationAsSeen:t,markNotificationAsUnread:s,deleteNotification:o,archiveNotification:r,unarchiveNotification:c}=M(),i=()=>t(e),u=()=>n(e),d=()=>s(e),a=()=>o(e),f=()=>r(e),l=()=>c(e);return g(p({},e),{customAttributes:Te(e.customAttributes),readAt:_(e.readAt),seenAt:_(e.seenAt),sentAt:_(e.sentAt),archivedAt:_(e.archivedAt),isSeen:!m.isNil(e.seenAt),isRead:!m.isNil(e.readAt),isArchived:!m.isNil(e.archivedAt),sanitizedContent:e.content,markAsSeen:i,markAsRead:u,markAsUnread:d,delete:a,archive:f,unarchive:l})}function oe(e,n){y.useEffect(()=>()=>{n?n(e):e.markAsSeen()},[])}function ze(e,n){const t=se(e);return oe(t,n),t}class Le{constructor(n="/notification_preferences"){$(this,"remotePathOrUrl");this.remotePathOrUrl=n}async get(){const n=this.remotePathOrUrl,t=await E(n);return b.default.camelizeKeys(t)}async update(n){const t=this.remotePathOrUrl,s=b.default.decamelizeKeys({notificationPreferences:n}),o=await V(t,s);return b.default.camelizeKeys(o)}}const Be=L.default((e,n)=>({categories:[],_repository:new Le,fetch:async()=>{const{_repository:t}=n();try{const{notificationPreferences:s}=await t.get();e(g(p({},s),{lastFetchedAt:Date.now()}))}catch(s){e({categories:[],lastFetchedAt:Date.now()})}},save:async t=>{const{_repository:s}=n();try{const{notificationPreferences:o}=await s.update(t);e(g(p({},o),{lastFetchedAt:Date.now()}))}catch(o){e({categories:[],lastFetchedAt:Date.now()})}}})),Je=Be;exports.MagicBellProvider=Oe;exports.RealtimeListener=Z;exports.WebPushNotificationsSubscriber=Fe;exports.buildStore=B;exports.clientSettings=U;exports.deleteAPI=G;exports.eventAggregator=F;exports.fetchAPI=E;exports.postAPI=S;exports.pushEventAggregator=Y;exports.putAPI=V;exports.secondsToDate=_;exports.toDate=ne;exports.toUnix=Ke;exports.useBell=De;exports.useConfig=K;exports.useMagicBellEvent=N;exports.useNotification=ze;exports.useNotificationFactory=se;exports.useNotificationPreferences=Je;exports.useNotificationStoresCollection=M;exports.useNotificationUnmount=oe;exports.useNotifications=te; | ||
"use strict";var ie=Object.defineProperty,re=Object.defineProperties;var ce=Object.getOwnPropertyDescriptors;var j=Object.getOwnPropertySymbols;var J=Object.prototype.hasOwnProperty,H=Object.prototype.propertyIsEnumerable;var T=(e,n,t)=>n in e?ie(e,n,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[n]=t,p=(e,n)=>{for(var t in n||(n={}))J.call(n,t)&&T(e,t,n[t]);if(j)for(var t of j(n))H.call(n,t)&&T(e,t,n[t]);return e},g=(e,n)=>re(e,ce(n));var q=(e,n)=>{var t={};for(var s in e)J.call(e,s)&&n.indexOf(s)<0&&(t[s]=e[s]);if(e!=null&&j)for(var s of j(e))n.indexOf(s)<0&&H.call(e,s)&&(t[s]=e[s]);return t};var $=(e,n,t)=>(T(e,typeof n!="symbol"?n+"":n,t),t);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});require("tiny-warning");const z=require("react/jsx-runtime"),y=require("react"),ae=require("magicbell/user-client"),ue=require("zustand/vanilla"),le=require("zustand"),fe=require("humps"),de=require("immer"),m=require("ramda"),he=require("mitt"),me=require("dayjs"),pe=require("dayjs/plugin/localizedFormat"),Ae=require("dayjs/plugin/relativeTime"),ge=require("dayjs/plugin/updateLocale"),x=e=>e&&typeof e=="object"&&"default"in e?e:{default:e},ye=x(ue),L=x(le),b=x(fe),P=x(de),W=x(he),I=x(me),ve=x(pe),Pe=x(Ae),we=x(ge),Ne=ye.default((e,n)=>{let t=null,s="";return{apiKey:"",userEmail:void 0,userExternalId:void 0,userKey:void 0,clientId:Math.random().toString(36).substring(2)+Date.now(),serverURL:"https://api.magicbell.com",appInfo:void 0,getClient(){const o=n(),r=JSON.stringify([o.apiKey,o.userEmail,o.userExternalId,o.userKey]);return r!==s&&(s=r,t=new ae.UserClient({userExternalId:o.userExternalId,userEmail:o.userEmail,userHmac:o.userKey,apiKey:o.apiKey,host:o.serverURL,appInfo:o.appInfo||{name:"@magicbell/react-headless",version:"4.5.1"}})),t}}}),U=Ne;function D(e,n,t,s){const o=U.getState().getClient(),r=s?Object.fromEntries(Object.entries(s).map(([c,i])=>[c,String(i)])):void 0;return o.request({method:e,path:n,data:t,params:r})}function E(e,n){return D("GET",e,void 0,n)}function S(e,n,t){return D("POST",e,n,t)}function G(e,n){return D("DELETE",e,void 0,n)}function V(e,n){return D("PUT",e,n)}class xe{constructor(n="/config"){$(this,"remotePathOrUrl");this.remotePathOrUrl=n}async get(){const n=await E(this.remotePathOrUrl);return b.default.camelizeKeys(n)}}const Se=L.default((e,n)=>({channels:void 0,inbox:void 0,ws:void 0,lastFetchedAt:void 0,_repository:new xe,fetch:async()=>{const{_repository:t}=n(),s=await t.get();e(g(p({},s),{lastFetchedAt:Date.now()}))}})),K=Se;class be{constructor(n){$(this,"remotePathOrUrl");this.remotePathOrUrl=n}async get(n){const t=`${this.remotePathOrUrl}/${n}`,s=await E(t);return b.default.camelizeKeys(s)}async findBy(n){try{const t=await E(this.remotePathOrUrl,n);return b.default.camelizeKeys(t)}catch(t){if(/Network Error/.test(t.message))return;throw t}}delete(n){const t=`${this.remotePathOrUrl}/${n}`;return G(t).then(()=>!0).catch(()=>!1)}}class X extends be{constructor(n="/notifications"){super(n)}archive(n){const t=`${this.remotePathOrUrl}/${n}/archive`;return S(t).then(()=>!0).catch(()=>!1)}unarchive(n){const t=`${this.remotePathOrUrl}/${n}/unarchive`;return S(t).then(()=>!0).catch(()=>!1)}markAsRead(n){const t=`${this.remotePathOrUrl}/${n}/read`;return S(t).then(()=>!0).catch(()=>!1)}markAsUnread(n){const t=`${this.remotePathOrUrl}/${n}/unread`;return S(t).then(()=>!0).catch(()=>!1)}markAllAsSeen(n){const t=`${this.remotePathOrUrl}/seen`;return S(t,void 0,n).then(()=>!0).catch(()=>!1)}markAllAsRead(n){const t=`${this.remotePathOrUrl}/read`;return S(t,void 0,n).then(()=>!0).catch(()=>!1)}}const Y=W.default(),F=W.default();function v(e,n,t){t==="remote"&&Y.emit(e,n),F.emit(e,{data:n,source:t})}function Ce(e){const{clientId:n}=U.getState(),t=e.name.replace(/\//gi,"."),s=e.data;return s.client_id&&s.client_id===n?Promise.resolve(!1):typeof s.id=="string"?t==="notifications.delete"?(v(t,s,"remote"),Promise.resolve(!0)):new X().get(s.id).then(c=>(v(t,c.notification,"remote"),!0)):(v(t,s,"remote"),Promise.resolve(!0))}const ke={context:{},total:0,totalPages:0,perPage:0,currentPage:1,unreadCount:0,unseenCount:0,notifications:[]};function B(e){return p(p({},ke),e)}function _e(e,n,t={reset:!1}){const c=n,{notifications:s=[]}=c,o=q(c,["notifications"]),r=t.reset?s:m.uniqBy(i=>i.id,t.prepend?[...s,...e.notifications]:[...e.notifications,...s]);return p({context:e.context,notifications:r},o)}function Ee(e,n){return e===n||e!==e&&n!==n}function Q(e){return Array.isArray(e)?e:String(e).split(",")}function w(e,n,t=Ee){const s=[];return n=p({archived:!1},n),Object.keys(n).forEach(o=>{const r=n[o];(o==="read"&&!t(!m.isNil(e.readAt),r)||o==="seen"&&!t(!m.isNil(e.seenAt),r)||o==="archived"&&!t(!m.isNil(e.archivedAt),r)||o==="categories"&&Q(r).every(c=>!t(e.category,c))||o==="topics"&&Q(r).every(c=>!t(e.topic,c))||Object.hasOwnProperty.call(e,o)&&!t(e[o],r))&&s.push(o)}),{result:s.length===0,delta:s}}function k(){return Math.floor(Date.now()/1e3)}const Ie=L.default((e,n)=>({stores:{},_repository:new X,setStore:(t,s={},o={})=>{e(P.default(r=>{r.stores[t]=B(g(p({},o),{context:s}))}))},fetchStore:async(t,s={},o={})=>{const{stores:r,_repository:c}=n(),i=r[t];if(i){const u=await c.findBy(p(p({},i.context),s));if(!u)return;e(P.default(d=>{d.stores[t]=_e(i,g(p({},u),{lastFetchedAt:new Date}),o)}))}else console.error(`Store not found. Define a store with the ${t} ID`)},fetchAllStores:async(t={},s={})=>{const{stores:o,fetchStore:r}=n(),i=Object.keys(o).map(u=>r(u,t,s));await Promise.all(i)},markNotificationAsSeen:t=>{const{stores:s}=n(),o=t.id;v("notifications.seen",t,"local"),e(P.default(r=>{for(const c in s){const{notifications:i,unseenCount:u}=s[c],d=m.findIndex(m.propEq("id",o),i);d>-1&&(i[d].seenAt||(r.stores[c].unseenCount=Math.max(0,u-1),r.stores[c].notifications[d]=m.mergeRight(i[d],{seenAt:k()})))}}))},markNotificationAsRead:t=>{const{stores:s,_repository:o}=n(),{id:r}=t,c=o.markAsRead(r);return v("notifications.read",t,"local"),e(P.default(i=>{const u=k(),d={readAt:u,seenAt:u};for(const a in s){const{total:f,notifications:l,context:h,unreadCount:A,unseenCount:O}=s[a],R=m.findIndex(m.propEq("id",r),l);if(R>-1){t.readAt||(i.stores[a].unreadCount=Math.max(0,A-1)),t.seenAt||(i.stores[a].unseenCount=Math.max(0,O-1));const C=m.mergeRight(l[R],d);w(C,h).result?i.stores[a].notifications[R]=C:(i.stores[a].total=Math.max(0,f-1),i.stores[a].notifications.splice(R,1))}else{const C=m.mergeRight(t,d);w(C,h).result&&(i.stores[a].total+=1,i.stores[a].notifications.push(C))}}})),c},markNotificationAsUnread:t=>{const{stores:s,_repository:o}=n(),{id:r}=t,c=o.markAsUnread(r);return v("notifications.unread",t,"local"),e(P.default(i=>{const u={readAt:null};for(const d in s){const{notifications:a,context:f}=s[d],l=m.findIndex(m.propEq("id",r),a);if(l>-1){const h=m.mergeRight(a[l],u);w(h,f).result?(t.readAt&&(i.stores[d].unreadCount+=1),i.stores[d].notifications[l]=h):(i.stores[d].total=Math.max(0,i.stores[d].total-1),i.stores[d].notifications.splice(l,1))}else{const h=m.mergeRight(t,u);w(h,f).result&&(i.stores[d].total+=1,t.readAt&&(i.stores[d].unreadCount+=1),i.stores[d].notifications.push(h))}}})),c},archiveNotification:(t,s={})=>{const{stores:o,_repository:r}=n(),{id:c}=t;let i=Promise.resolve(!0);return s.persist!==!1&&(i=r.archive(c),v("notifications.archived",t,"local")),e(P.default(u=>{const a={archivedAt:k()};for(const f in o){const l=o[f],h=m.findIndex(m.propEq("id",c),l.notifications);if(h>-1){const A=p(p({},l.notifications[h]),a);w(A,l.context).result?u.stores[f].notifications[h]=A:(t.readAt||(u.stores[f].unreadCount=Math.max(0,l.unreadCount-1)),t.seenAt||(u.stores[f].unseenCount=Math.max(0,l.unseenCount-1)),u.stores[f].total=Math.max(0,l.total-1),u.stores[f].notifications.splice(h,1))}else{const A=p(p({},t),a);w(A,l.context).result&&(t.readAt||(u.stores[f].unreadCount+=1),t.seenAt||(u.stores[f].unseenCount+=1),u.stores[f].total+=1,u.stores[f].notifications.push(A))}}})),i},unarchiveNotification:(t,s={})=>{const{stores:o,_repository:r}=n(),{id:c}=t;let i=Promise.resolve(!0);return s.persist!==!1&&(i=r.unarchive(c),v("notifications.unarchived",t,"local")),e(P.default(u=>{const d={archivedAt:null};for(const a in o){const f=o[a],l=m.findIndex(m.propEq("id",c),f.notifications);if(l>-1){const h=p(p({},f.notifications[l]),d);w(h,f.context).result?u.stores[a].notifications[l]=h:(t.readAt||(u.stores[a].unreadCount=Math.max(0,f.unreadCount-1)),t.seenAt||(u.stores[a].unseenCount=Math.max(0,f.unseenCount-1)),u.stores[a].total=Math.max(0,f.total-1),u.stores[a].notifications.splice(l,1))}else{const h=p(p({},t),d);w(h,f.context).result&&(t.readAt||(u.stores[a].unreadCount+=1),t.seenAt||(u.stores[a].unseenCount+=1),u.stores[a].total+=1,u.stores[a].notifications.push(h))}}})),i},deleteNotification:(t,s={})=>{const{stores:o,_repository:r}=n(),c=t.id;let i=Promise.resolve(!0);return s.persist!==!1&&(i=r.delete(c),v("notifications.delete",t,"local")),e(P.default(u=>{for(const d in o){const{notifications:a,total:f,unseenCount:l,unreadCount:h}=o[d],A=m.findIndex(m.propEq("id",c),a);if(A>-1){const O=a[A];O.seenAt||(u.stores[d].unseenCount=Math.max(0,l-1)),O.readAt||(u.stores[d].unreadCount=Math.max(0,h-1)),u.stores[d].total=Math.max(0,f-1),u.stores[d].notifications.splice(A,1)}}})),i},markAllAsSeen:(t={persist:!0,updateModels:!0})=>{var c;const{stores:s,_repository:o}=n();let r=Promise.resolve(!0);if(t.persist!==!1){const i=t.storeId?(c=s[t.storeId])==null?void 0:c.context:{};r=o.markAllAsSeen(i),v("notifications.seen.all",null,"local")}return e(P.default(i=>{const u=new Map,d=k();for(const a in s){const{context:f}=s[a];if(i.stores[a].unseenCount=0,t.updateModels!==!1){if(f.seen!==!0)for(const l of i.stores[a].notifications)l.seenAt||(l.seenAt=d,u.set(l.id,l));f.seen===!1&&(i.stores[a].notifications=[],i.stores[a].total=0)}}for(const a in s){const{context:f}=s[a];if(f.seen!==!0)continue;const l=i.stores[a].notifications;for(const h of u.values())w(h,f).result&&!l.find(A=>A.id===h.id)&&(l.push(h),i.stores[a].total+=1)}})),r},markAllAsRead:(t={persist:!0,updateModels:!0})=>{var c;const{stores:s,_repository:o}=n();let r=Promise.resolve(!0);if(t.persist!==!1){const i=t.storeId?(c=s[t.storeId])==null?void 0:c.context:{};r=o.markAllAsRead(i),v("notifications.read.all",null,"local")}return e(P.default(i=>{const u=new Map,d=k();for(const a in s){const{context:f}=s[a];if(i.stores[a].unreadCount=0,i.stores[a].unseenCount=0,t.updateModels!==!1){if(f.read!==!0)for(const l of i.stores[a].notifications)l.readAt||(l.readAt=d,l.seenAt=d,u.set(l.id,l));f.read===!1&&(i.stores[a].notifications=[],i.stores[a].total=0)}}for(const a in s){const{context:f}=s[a];if(f.read!==!0)continue;const l=i.stores[a].notifications;for(const h of u.values())w(h,f).result&&!l.find(A=>A.id===h.id)&&(l.push(h),i.stores[a].total+=1)}})),r}})),M=Ie;function N(e,n,t={source:"any"}){y.useEffect(()=>{const s=(o={})=>{t.source==="remote"&&o.source!=="remote"||t.source==="local"&&o.source!=="local"||n(o.data,o.source)};return F.on(e,s),()=>{F.off(e,s)}},[])}function Z(){const e=M(),n=U.getState(),t=n.getClient(),s=n.apiKey,o=n.userExternalId||n.userEmail,r=()=>e.fetchAllStores({page:1},{reset:!0}),c=()=>e.fetchAllStores({page:1},{prepend:!0}),i=()=>e.markAllAsSeen({persist:!1}),u=()=>e.markAllAsRead({persist:!1}),d=l=>e.deleteNotification(l,{persist:!1}),a=l=>e.archiveNotification(l,{persist:!1}),f=l=>e.unarchiveNotification(l,{persist:!1});return y.useEffect(()=>{if(!s||!o)return;const l=t.listen();return l.forEach(h=>{!h||Ce(h)}),()=>l.close()},[t,s,o]),N("reconnected",r),N("notifications.new",c,{source:"remote"}),N("notifications.seen.all",i,{source:"remote"}),N("notifications.read.all",u,{source:"remote"}),N("notifications.read",r,{source:"remote"}),N("notifications.unread",r,{source:"remote"}),N("notifications.delete",d,{source:"remote"}),N("notifications.archived",a,{source:"remote"}),N("notifications.unarchived",f,{source:"remote"}),null}function Ue(t){var s=t,{serverURL:e}=s,n=q(s,["serverURL"]);const o=n;return e&&(o.serverURL=e),U.setState(o),o}function Me(e){const n={};return e.forEach(t=>{const{defaultQueryParams:s,defaults:o={}}=t;n[t.id]=B(p({context:s},o))}),M.setState({stores:n}),n}function Oe(o){var r=o,{children:e,stores:n=[{id:"default",defaultQueryParams:{}}],disableRealtime:t}=r,s=q(r,["children","stores","disableRealtime"]);y.useState(()=>Ue(s)),y.useEffect(()=>{Me(n)},[]);const c=K();return y.useEffect(()=>{c.lastFetchedAt||c.fetch()},[c]),z.jsxs(z.Fragment,{children:[t?null:z.jsx(Z,{}),e]})}function Re(e){const n="=".repeat((4-e.length%4)%4),t=(e+n).replace(/-/g,"+").replace(/_/g,"/"),s=window.atob(t),o=new Uint8Array(s.length);for(let r=0;r<s.length;++r)o[r]=s.charCodeAt(r);return o}function ee(e){return S("/web_push_subscriptions",{web_push_subscription:{data:e}})}function je(e,n){const t=Re(n);return e.subscribe({userVisibleOnly:!0,applicationServerKey:t})}async function qe(e,n){const t=m.path(["webPush","config","vapidAuthentication","publicKey"],n.channels),s=await je(e,t);return ee(s.toJSON())}function $e(e,n,t="web.com.magicbell-notifications"){const s=window.safari.pushNotification.permission(t);return s.permission==="granted"?Promise.resolve(s):s.permission==="denied"?Promise.reject(!1):new Promise(function(o,r){window.safari.pushNotification.requestPermission(n,t,{authenticationToken:e},function(c){if(c.deviceToken){const i={endpoint:c.deviceToken,keys:{websitePushID:t},platform:"safari"};ee(i).then(u=>{o(u)}).catch(u=>{r(u)})}else{const i=new Error("Permission was denied");r(i)}})})}function Fe({children:e,serviceWorkerPath:n="/service-worker.js",skipServiceWorkerRegistration:t=!1}){const s=K(),o="safari"in window,r="PushManager"in window;return y.useEffect(()=>{t||navigator.serviceWorker.register(n)},[n,t]),e({createSubscription:async()=>{var i,u,d;if(!s)return Promise.reject(new Error("Context for MagicBell was not found"));if(o){const a=m.path(["safari","authenticationToken"],(i=s.channels)==null?void 0:i.webPush.config),f=m.path(["safari","websitePushId"],(u=s.channels)==null?void 0:u.webPush.config),l=m.path(["safari","webServiceUrl"],(d=s.channels)==null?void 0:d.webPush.config);return $e(a,l,f)}if(r)return navigator.serviceWorker.ready.then(async a=>{await qe(a.pushManager,s)})},isPushAPISupported:r})}function te(e="default"){const{stores:n,fetchStore:t,markAllAsSeen:s,markAllAsRead:o}=M(),r=K(),c=n[e],i=y.useCallback((f,l)=>t(e,f,l),[t,e]),u=y.useCallback((f={},l)=>{const h=c.currentPage+1;return t(e,g(p({},f),{page:h}),l)},[t,e,c==null?void 0:c.currentPage]);y.useEffect(()=>{!c||r.lastFetchedAt&&!c.lastFetchedAt&&i({page:1})},[r.lastFetchedAt,c,i]);const d=y.useCallback(f=>o(g(p({},f),{storeId:e})),[o,e]),a=y.useCallback(f=>s(g(p({},f),{storeId:e})),[s,e]);return c?g(p({},c),{isEmpty:c.notifications.length===0,hasNextPage:c.currentPage<c.totalPages,fetch:i,fetchNextPage:u,markAllAsSeen:a,markAllAsRead:d}):null}function De({storeId:e}={}){const n=te(e),t=()=>n&&n.unseenCount>0?n==null?void 0:n.markAllAsSeen({updateModels:!1}):Promise.resolve(!0);return n?g(p({},n),{markAllAsSeen:t}):null}I.default.extend(ve.default);I.default.extend(Pe.default);I.default.extend(we.default);function _(e){return e?ne(e*1e3):null}function ne(e){return I.default(e)}function Ke(e){return I.default(e).unix()}function Te(e){if(m.isNil(e))return null;if(typeof e=="string")try{return JSON.parse(e)}catch(n){}return e}function se(e){const{markNotificationAsRead:n,markNotificationAsSeen:t,markNotificationAsUnread:s,deleteNotification:o,archiveNotification:r,unarchiveNotification:c}=M(),i=()=>t(e),u=()=>n(e),d=()=>s(e),a=()=>o(e),f=()=>r(e),l=()=>c(e);return g(p({},e),{customAttributes:Te(e.customAttributes),readAt:_(e.readAt),seenAt:_(e.seenAt),sentAt:_(e.sentAt),archivedAt:_(e.archivedAt),isSeen:!m.isNil(e.seenAt),isRead:!m.isNil(e.readAt),isArchived:!m.isNil(e.archivedAt),sanitizedContent:e.content,markAsSeen:i,markAsRead:u,markAsUnread:d,delete:a,archive:f,unarchive:l})}function oe(e,n){y.useEffect(()=>()=>{n?n(e):e.markAsSeen()},[])}function ze(e,n){const t=se(e);return oe(t,n),t}class Le{constructor(n="/notification_preferences"){$(this,"remotePathOrUrl");this.remotePathOrUrl=n}async get(){const n=this.remotePathOrUrl,t=await E(n);return b.default.camelizeKeys(t)}async update(n){const t=this.remotePathOrUrl,s=b.default.decamelizeKeys({notificationPreferences:n}),o=await V(t,s);return b.default.camelizeKeys(o)}}const Be=L.default((e,n)=>({categories:[],_repository:new Le,fetch:async()=>{const{_repository:t}=n();try{const{notificationPreferences:s}=await t.get();e(g(p({},s),{lastFetchedAt:Date.now()}))}catch(s){e({categories:[],lastFetchedAt:Date.now()})}},save:async t=>{const{_repository:s}=n();try{const{notificationPreferences:o}=await s.update(t);e(g(p({},o),{lastFetchedAt:Date.now()}))}catch(o){e({categories:[],lastFetchedAt:Date.now()})}}})),Je=Be;exports.MagicBellProvider=Oe;exports.RealtimeListener=Z;exports.WebPushNotificationsSubscriber=Fe;exports.buildStore=B;exports.clientSettings=U;exports.deleteAPI=G;exports.eventAggregator=F;exports.fetchAPI=E;exports.postAPI=S;exports.pushEventAggregator=Y;exports.putAPI=V;exports.secondsToDate=_;exports.toDate=ne;exports.toUnix=Ke;exports.useBell=De;exports.useConfig=K;exports.useMagicBellEvent=N;exports.useNotification=ze;exports.useNotificationFactory=se;exports.useNotificationPreferences=Je;exports.useNotificationStoresCollection=M;exports.useNotificationUnmount=oe;exports.useNotifications=te; | ||
//# sourceMappingURL=magicbell-react-headless.cjs.min.js.map |
/** | ||
* @license @magicbell/react-headless v4.5.0 | ||
* @license @magicbell/react-headless v4.5.1 | ||
* | ||
@@ -83,3 +83,3 @@ * Copyright (c) MagicBell Inc. and its affiliates. | ||
name: "@magicbell/react-headless", | ||
version: "4.5.0" | ||
version: "4.5.1" | ||
} | ||
@@ -86,0 +86,0 @@ }); |
/** | ||
* @license @magicbell/react-headless v4.5.0 | ||
* @license @magicbell/react-headless v4.5.1 | ||
* | ||
@@ -66,3 +66,3 @@ * Copyright (c) MagicBell Inc. and its affiliates. | ||
name: "@magicbell/react-headless", | ||
version: "4.5.0" | ||
version: "4.5.1" | ||
} | ||
@@ -69,0 +69,0 @@ })), e; |
{ | ||
"name": "@magicbell/react-headless", | ||
"version": "4.5.0", | ||
"version": "4.5.1", | ||
"description": "Hooks to build a notification inbox", | ||
@@ -82,3 +82,3 @@ "author": "MagicBell <bot@magicbell.io> (https://magicbell.com/)", | ||
"lodash-es": "^4.17.21", | ||
"magicbell": "3.1.1", | ||
"magicbell": "3.1.2", | ||
"mitt": "^3.0.1", | ||
@@ -85,0 +85,0 @@ "ramda": "^0.28.0", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
+ Addedmagicbell@3.1.2(transitive)
- Removedmagicbell@3.1.1(transitive)
Updatedmagicbell@3.1.2