UNPKG

blast-client

Version:

blast client

1 lines 30.4 kB
{"version":3,"sources":["../src/providers/react.tsx","../src/managers/sw.ts","../src/events/subscribers.ts","../src/helpers/cookis.ts","../src/builders/PluginBuilder.ts","../src/core.ts","../src/hooks/useUserId.ts","../src/hooks/usePushNotificationListener.ts","../src/integrations/react/dialog/index.tsx","../src/hooks/useRoot.ts","../src/integrations/react/dialog/using.tsx","../src/integrations/react/alert/index.tsx","../src/integrations/react/alert/using.tsx"],"sourcesContent":["import { createContext, ReactNode, useContext, useState } from \"react\";\r\n\r\ntype AlertType = {\r\n alertId: string;\r\n title: string;\r\n content: string;\r\n timeout: number;\r\n type?: \"success\";\r\n};\r\n\r\ninterface Props {\r\n alerts: AlertType[];\r\n addAlert: (data: AlertType) => void;\r\n removeAlert: (alertId: string) => void;\r\n}\r\n\r\nconst BlastContext = createContext<Props | undefined>(undefined);\r\n\r\nexport default function BlastProvider({ children }: { children: ReactNode }) {\r\n const [alerts, setAlerts] = useState<AlertType[]>([]);\r\n\r\n const addAlert = (data: AlertType) => {\r\n setAlerts([...alerts, data]);\r\n };\r\n\r\n const removeAlert = (alertId: string) => {\r\n setAlerts((prev) => prev.filter((item) => item.alertId !== alertId));\r\n };\r\n\r\n return (\r\n <BlastContext.Provider value={{ alerts, addAlert, removeAlert }}>\r\n {children}\r\n </BlastContext.Provider>\r\n );\r\n}\r\n\r\nexport const useAlert = () => {\r\n const context = useContext(BlastContext);\r\n\r\n if (!context) throw new Error(\"error\");\r\n\r\n return context;\r\n};\r\n","import { v4 } from \"uuid\";\r\nimport { NewSubscribeEvent } from \"@/events/subscribers\";\r\nimport { SubscribeFunctionType } from \"@/types\";\r\nimport { getCookie, setCookie } from \"@/helpers/cookis\";\r\n\r\nexport class Sw {\r\n private hasClickHandler = false;\r\n\r\n constructor(\r\n private swPath: string,\r\n private publicKey: string,\r\n private scope: string\r\n ) {}\r\n\r\n private getOrCreateUserId(): string {\r\n let userId = getCookie(\"user_id\");\r\n\r\n if (!userId) {\r\n userId = v4();\r\n setCookie(\"user_id\", userId, {\r\n path: \"/\",\r\n });\r\n }\r\n\r\n return userId;\r\n }\r\n\r\n private async requestNotificationPermission(): Promise<NotificationPermission> {\r\n return await Notification.requestPermission();\r\n }\r\n\r\n private async registerServiceWorker(): Promise<ServiceWorkerRegistration> {\r\n const registration = await navigator.serviceWorker.register(this.swPath, {\r\n scope: this.scope ?? \"/\",\r\n });\r\n\r\n registration.update();\r\n\r\n if (registration.installing || registration.waiting) {\r\n const sw = registration.installing || registration.waiting;\r\n await new Promise<void>((resolve) => {\r\n sw?.addEventListener(\"statechange\", () => {\r\n if (sw.state === \"activated\") resolve();\r\n });\r\n });\r\n } else if (!registration.active) {\r\n await navigator.serviceWorker.ready;\r\n }\r\n\r\n return registration;\r\n }\r\n\r\n private async getOrCreateSubscription(\r\n reg: ServiceWorkerRegistration,\r\n subscribeUser: SubscribeFunctionType\r\n ): Promise<PushSubscription> {\r\n const existingSubscription = await reg.pushManager.getSubscription();\r\n\r\n const newSubscription = await reg.pushManager.subscribe({\r\n userVisibleOnly: true,\r\n applicationServerKey: this.urlBase64ToUint8Array(this.publicKey),\r\n });\r\n\r\n const hasChanged =\r\n !existingSubscription ||\r\n existingSubscription.endpoint !== newSubscription.endpoint;\r\n\r\n if (hasChanged) {\r\n const userId = this.getOrCreateUserId();\r\n\r\n window.dispatchEvent(\r\n NewSubscribeEvent({\r\n sub: newSubscription.toJSON(),\r\n userAgent: navigator.userAgent,\r\n userId,\r\n })\r\n );\r\n\r\n await subscribeUser(\r\n newSubscription.toJSON(),\r\n navigator.userAgent,\r\n userId\r\n );\r\n }\r\n\r\n return newSubscription;\r\n }\r\n\r\n private urlBase64ToUint8Array(base64String: string) {\r\n const padding = \"=\".repeat((4 - (base64String.length % 4)) % 4);\r\n const base64 = (base64String + padding)\r\n .replace(/-/g, \"+\")\r\n .replace(/_/g, \"/\");\r\n const rawData = window.atob(base64);\r\n const outputArray = new Uint8Array(rawData.length);\r\n\r\n for (let i = 0; i < rawData.length; ++i) {\r\n outputArray[i] = rawData.charCodeAt(i);\r\n }\r\n\r\n return outputArray;\r\n }\r\n\r\n async init(\r\n subscribeUser: SubscribeFunctionType,\r\n onMessage?: (type: \"subscribed\" | \"denied\" | \"error\") => void,\r\n time?: number,\r\n repeatCount?: number\r\n ) {\r\n const trigger = (type: \"subscribed\" | \"denied\" | \"error\") => {\r\n if (onMessage) {\r\n onMessage(type);\r\n\r\n const maxRepeats = Math.min(repeatCount ?? 1, 4);\r\n\r\n if (time && typeof time === \"number\" && time > 0 && maxRepeats > 1) {\r\n let count = 1;\r\n\r\n const interval = setInterval(() => {\r\n count++;\r\n onMessage(type);\r\n\r\n if (count >= maxRepeats) {\r\n clearInterval(interval);\r\n }\r\n }, time);\r\n }\r\n }\r\n };\r\n\r\n try {\r\n if (!(\"serviceWorker\" in navigator) || !(\"PushManager\" in window)) return;\r\n\r\n const currentPermission = Notification.permission;\r\n\r\n if (currentPermission === \"denied\") {\r\n trigger(\"denied\");\r\n return;\r\n }\r\n\r\n let permission: NotificationPermission = currentPermission;\r\n\r\n if (currentPermission === \"default\") {\r\n permission = await this.requestNotificationPermission();\r\n }\r\n\r\n if (permission !== \"granted\") {\r\n trigger(\"denied\");\r\n return;\r\n }\r\n\r\n const registration = await this.registerServiceWorker();\r\n await this.getOrCreateSubscription(registration, subscribeUser);\r\n\r\n trigger(\"subscribed\");\r\n } catch (error) {\r\n console.error(\"Service Worker init error:\", error);\r\n trigger(\"error\");\r\n }\r\n }\r\n\r\n async clickNotification(\r\n setClick: (\r\n notificationId: string,\r\n subscribeId: string\r\n ) => Promise<{ data: any; ok: boolean }>\r\n ) {\r\n if (!(\"serviceWorker\" in navigator) || !(\"PushManager\" in window)) return;\r\n if (this.hasClickHandler) return;\r\n\r\n const handleMessage = async (ev: MessageEvent<any>) => {\r\n if (ev.data?.type === \"NOTIFICATION_CLICKED\") {\r\n const { notificationId, subscribeId } = ev.data.notification_data;\r\n\r\n this.hasClickHandler = true;\r\n\r\n const { data, ok } = await setClick(notificationId, subscribeId);\r\n\r\n this.hasClickHandler = false;\r\n\r\n if (!ok)\r\n return console.error(\r\n `[ Error to add click rate ]: ${data?.message || data}`\r\n );\r\n }\r\n };\r\n\r\n navigator.serviceWorker.addEventListener(\"message\", handleMessage);\r\n }\r\n}\r\n","export const NewSubscribeEvent = (data: any) => {\r\n return new CustomEvent(\"new-subscribe\", {\r\n detail: data,\r\n });\r\n};\r\n","import Cookies from \"js-cookie\";\r\n\r\nexport function getCookie(name: string): string | undefined {\r\n return Cookies.get(name);\r\n}\r\n\r\nexport function setCookie(\r\n name: string,\r\n value: string,\r\n options?: Cookies.CookieAttributes\r\n): void {\r\n Cookies.set(name, value, {\r\n ...options,\r\n secure: process.env?.NODE_ENV === \"production\",\r\n });\r\n}\r\n\r\nexport function removeCookie(name: string): void {\r\n Cookies.remove(name, { path: \"/\" });\r\n}\r\n","import { type Sw } from \"@/managers/sw\";\r\n\r\nexport class PluginBuilder {\r\n constructor(private sw: Sw) {}\r\n\r\n public async clickNotification(\r\n setClick: (\r\n notificationId: string,\r\n subscribeId: string\r\n ) => Promise<{ data: any; ok: boolean }>\r\n ) {\r\n return await this.sw.clickNotification(setClick);\r\n }\r\n}\r\n","import { SubscribeFunctionType } from \"@/types\";\r\nimport { Sw } from \"@/managers/sw\";\r\nimport { PluginBuilder } from \"@/builders/PluginBuilder\";\r\n\r\nexport class BlastClient {\r\n private sw: Sw;\r\n public plugins: PluginBuilder;\r\n\r\n constructor(swPath: string, publicKey: string, scope: string) {\r\n this.sw = new Sw(swPath, publicKey, scope);\r\n this.plugins = new PluginBuilder(this.sw);\r\n }\r\n\r\n public async run(\r\n subscribeUser: SubscribeFunctionType,\r\n onMessage?: (type: \"subscribed\" | \"denied\" | \"error\") => void,\r\n time?: number,\r\n repeatCount?: number\r\n ) {\r\n try {\r\n await this.sw.init(subscribeUser, onMessage, time, repeatCount);\r\n return \"Auto inject complete\";\r\n } catch (error) {\r\n return error as Error;\r\n }\r\n }\r\n}\r\n","import { getCookie, setCookie } from \"@/helpers/cookis\";\r\nimport { v4 } from \"uuid\";\r\n\r\nexport const useUserId = () => {\r\n let userId = getCookie(\"user_id\");\r\n\r\n if (!userId) {\r\n userId = v4();\r\n setCookie(\"user_id\", userId, {\r\n path: \"/\",\r\n secure: process.env.NODE_ENV !== \"devploment\",\r\n });\r\n }\r\n\r\n return userId;\r\n};\r\n","import { useEffect } from \"react\";\r\nimport { useAlert } from \"@/providers/react\";\r\nimport { v4 } from \"uuid\";\r\n\r\nexport function usePushNotificationListener() {\r\n const { addAlert } = useAlert();\r\n\r\n useEffect(() => {\r\n const handleMessage = (ev: MessageEvent<any>) => {\r\n if (ev.data?.type === \"PUSH_RECEIVED\") {\r\n const { notification } = ev.data;\r\n addAlert({\r\n alertId: v4(),\r\n content: notification.body,\r\n title: notification.title,\r\n timeout: 5000,\r\n });\r\n }\r\n };\r\n\r\n navigator.serviceWorker?.addEventListener(\"message\", handleMessage);\r\n\r\n return () => {\r\n navigator.serviceWorker?.removeEventListener(\"message\", handleMessage);\r\n };\r\n }, []);\r\n}\r\n","import { useEffect, useRef, useState } from \"react\";\r\nimport { motion, AnimatePresence } from \"framer-motion\";\r\nimport { DialogComponentsProps, DialogNotificationType } from \"@/types\";\r\nimport { useUserId } from \"@/hooks/useUserId\";\r\nimport { createPortal } from \"react-dom\";\r\nimport { root } from \"@/hooks/useRoot\";\r\n\r\nexport const DialogComponent = ({\r\n dialogs,\r\n addGets,\r\n}: DialogComponentsProps) => {\r\n const [current, setCurrent] = useState(0);\r\n const [visible, setVisible] = useState(true);\r\n const closeDialogRef = useRef<() => void>(() => {});\r\n const nextDialogRef = useRef<() => void>(() => {});\r\n const hasAddedUser = useRef(false);\r\n const userId = useUserId();\r\n\r\n const currentDialog = dialogs[current];\r\n\r\n const close = () => {\r\n setVisible(false);\r\n };\r\n\r\n const next = () => {\r\n if (current < dialogs.length - 1) {\r\n setCurrent((prev) => prev + 1);\r\n } else {\r\n close();\r\n }\r\n };\r\n\r\n closeDialogRef.current = close;\r\n nextDialogRef.current = next;\r\n\r\n useEffect(() => {\r\n const handleClose = () => closeDialogRef.current();\r\n window.addEventListener(\"dialog-close\", handleClose);\r\n return () => window.removeEventListener(\"dialog-close\", handleClose);\r\n }, []);\r\n\r\n useEffect(() => {\r\n // Helper log when dialog changes\r\n console.log(\r\n `[Dialog Helper] Showing dialog: ${\r\n currentDialog.dialogId || `dialog-${current}`\r\n }`\r\n );\r\n }, [currentDialog]);\r\n\r\n useEffect(() => {\r\n if (!currentDialog || !userId) return;\r\n if (hasAddedUser.current) return;\r\n\r\n const addUser = async () => {\r\n await addGets(currentDialog.dialogId!, userId);\r\n hasAddedUser.current = true;\r\n };\r\n\r\n addUser();\r\n }, [currentDialog, userId]);\r\n\r\n const handleButtonClick = (\r\n eventType: DialogNotificationType[\"buttons\"][0][\"event\"]\r\n ) => {\r\n if (eventType === \"post_message\") {\r\n const closeFn = () => closeDialogRef.current();\r\n const nextFn = () => nextDialogRef.current();\r\n\r\n window.dispatchEvent(\r\n new CustomEvent(\"dialog-message\", {\r\n detail: {\r\n dialogId: currentDialog.dialogId || `dialog-${current}`,\r\n close: closeFn,\r\n next: nextFn,\r\n },\r\n })\r\n );\r\n } else {\r\n next();\r\n }\r\n };\r\n\r\n const mainReturn = () => {\r\n return (\r\n <AnimatePresence>\r\n {visible && (\r\n <motion.div\r\n dir=\"ltr\"\r\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm p-4\"\r\n initial={{ opacity: 0 }}\r\n animate={{ opacity: 1 }}\r\n exit={{ opacity: 0 }}\r\n >\r\n <motion.div\r\n className=\"relative w-full max-w-lg rounded-3xl p-6 backdrop-blur-xl bg-white/10 dark:bg-white/5 ring-1 ring-white/20 text-white shadow-2xl overflow-hidden\"\r\n initial={{ scale: 0.95, y: 40, opacity: 0 }}\r\n animate={{ scale: 1, y: 0, opacity: 1 }}\r\n exit={{ scale: 0.95, y: 40, opacity: 0 }}\r\n transition={{ type: \"spring\", stiffness: 260, damping: 20 }}\r\n >\r\n {/* Glowing Border Effect */}\r\n <div className=\"absolute inset-0 rounded-3xl pointer-events-none z-[-1] before:absolute before:inset-0 before:rounded-3xl before:border before:border-white/20 before:backdrop-blur-md before:shadow-[0_0_30px_rgba(255,255,255,0.1)]\" />\r\n\r\n <h2 className=\"text-2xl font-extrabold tracking-wide\">\r\n {currentDialog.title}\r\n </h2>\r\n <p className=\"text-sm text-white/80 pt-2\">\r\n {currentDialog.content}\r\n </p>\r\n\r\n <div className=\"flex justify-end gap-3 pt-6 flex-wrap\">\r\n {currentDialog.buttons.map((btn, idx) => (\r\n <button\r\n key={idx}\r\n onClick={() => handleButtonClick(btn.event)}\r\n className=\"relative z-10 px-5 py-2.5 rounded-xl bg-gradient-to-br from-blue-500 to-indigo-600 hover:from-blue-600 hover:to-indigo-700 transition-all duration-300 shadow-lg shadow-indigo-800/30 font-medium text-white\"\r\n >\r\n {btn.content}\r\n </button>\r\n ))}\r\n </div>\r\n </motion.div>\r\n </motion.div>\r\n )}\r\n </AnimatePresence>\r\n );\r\n };\r\n\r\n return root ? createPortal(mainReturn(), root) : mainReturn();\r\n};\r\n","import { useCallback, useLayoutEffect } from \"react\";\r\n\r\nexport const root = (() => {\r\n if (typeof document === \"undefined\") return null;\r\n return document.getElementById(\"blast-root\");\r\n})();\r\n\r\nexport const appendRoot = () => {\r\n const set = useCallback(() => {\r\n if (\r\n typeof window === \"undefined\" ||\r\n typeof document === \"undefined\" ||\r\n typeof document.body === \"undefined\"\r\n )\r\n return;\r\n\r\n const existingElement = document.getElementById(\"blast-root\");\r\n if (existingElement) return;\r\n\r\n const div = document.createElement(\"div\");\r\n div.id = \"blast-root\";\r\n document.body.appendChild(div);\r\n }, []);\r\n\r\n useLayoutEffect(() => {\r\n set();\r\n }, [set]);\r\n};\r\n","import type { DialogProps } from \"@/types\";\r\nimport { DialogComponent } from \".\";\r\nimport { appendRoot } from \"@/hooks/useRoot\";\r\n\r\nexport default function Dialog({ dialogs, addGets }: DialogProps) {\r\n appendRoot();\r\n\r\n return dialogs?.length ? (\r\n <DialogComponent dialogs={dialogs} addGets={addGets} />\r\n ) : (\r\n <></>\r\n );\r\n}\r\n","import { useAlert } from \"@/providers/react\";\r\nimport { JSX, useEffect } from \"react\";\r\nimport { motion, AnimatePresence } from \"framer-motion\";\r\nimport { createPortal } from \"react-dom\";\r\nimport { root } from \"@/hooks/useRoot\";\r\n\r\ntype AlertType = {\r\n alertId: string;\r\n title: string;\r\n content: string;\r\n timeout: number;\r\n};\r\n\r\ninterface AlertComponentProps {\r\n renderAlert?: (alert: AlertType) => JSX.Element;\r\n}\r\n\r\nexport const AlertComponent = ({ renderAlert }: AlertComponentProps) => {\r\n const { removeAlert, alerts } = useAlert();\r\n\r\n useEffect(() => {\r\n alerts.forEach((alert) => {\r\n if (alert.timeout === Number.POSITIVE_INFINITY) return;\r\n\r\n const timer = setTimeout(() => {\r\n removeAlert(alert.alertId);\r\n }, alert.timeout);\r\n\r\n return () => clearTimeout(timer);\r\n });\r\n }, [alerts, removeAlert]);\r\n\r\n const mainReturn = () => {\r\n return (\r\n <AnimatePresence>\r\n {alerts.map((item, index) => {\r\n if (renderAlert) {\r\n return (\r\n <div\r\n key={item.alertId}\r\n className=\"fixed top-5 right-5 z-[9999999]\"\r\n style={{ maxWidth: \"320px\" }}\r\n >\r\n {renderAlert(item)}\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <motion.div\r\n initial={{ opacity: 0, x: 50, scale: 0.9 }}\r\n animate={{ opacity: 1, x: 0, scale: 1 }}\r\n exit={{ opacity: 0, x: 50, scale: 0.9 }}\r\n transition={{\r\n type: \"spring\",\r\n stiffness: 260,\r\n damping: 20,\r\n duration: 0.5,\r\n }}\r\n key={item.alertId}\r\n className=\"fixed top-5 right-5 z-[9999999] flex w-[320px] max-w-full items-center rounded-lg border border-purple-500 bg-gradient-to-r from-purple-900/30 to-black/60 p-4 text-white shadow-lg backdrop-blur-lg max-sm:right-auto max-sm:left-1/2 max-sm:w-[95%] max-sm:-translate-x-1/2\"\r\n >\r\n <div className=\"flex-grow pr-4\">\r\n <h5 className=\"mb-1 text-lg font-semibold tracking-wide\">\r\n {item.title}\r\n </h5>\r\n <p className=\"text-sm opacity-80\">{item.content}</p>\r\n </div>\r\n <div className=\"flex w-12 items-center justify-center text-purple-300\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n className=\"lucide lucide-bell h-7 w-7\"\r\n >\r\n <path d=\"M10.268 21a2 2 0 0 0 3.464 0\"></path>\r\n <path d=\"M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326\"></path>\r\n </svg>\r\n </div>\r\n </motion.div>\r\n );\r\n })}\r\n </AnimatePresence>\r\n );\r\n };\r\n\r\n return root ? createPortal(mainReturn(), root) : mainReturn();\r\n};\r\n","import { appendRoot } from \"@/hooks/useRoot\";\r\nimport { AlertComponent } from \".\";\r\n\r\nexport default function Alert() {\r\n appendRoot();\r\n\r\n return <AlertComponent />;\r\n}\r\n"],"mappings":"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","names":["createContext","useContext","useState","jsx","BlastContext","BlastProvider","children","alerts","setAlerts","addAlert","data","removeAlert","alertId","prev","item","useAlert","context","v4","NewSubscribeEvent","data","Cookies","getCookie","name","Cookies","setCookie","value","options","__spreadProps","__spreadValues","Sw","swPath","publicKey","scope","userId","getCookie","v4","setCookie","__async","_a","registration","sw","resolve","reg","subscribeUser","existingSubscription","newSubscription","NewSubscribeEvent","base64String","padding","base64","rawData","outputArray","i","onMessage","time","repeatCount","trigger","type","maxRepeats","count","interval","currentPermission","permission","error","setClick","handleMessage","ev","notificationId","subscribeId","data","ok","PluginBuilder","sw","setClick","__async","BlastClient","swPath","publicKey","scope","Sw","PluginBuilder","subscribeUser","onMessage","time","repeatCount","__async","error","v4","useUserId","userId","getCookie","setCookie","useEffect","v4","usePushNotificationListener","addAlert","useAlert","useEffect","_a","handleMessage","ev","notification","useEffect","useRef","useState","motion","AnimatePresence","createPortal","useCallback","useLayoutEffect","root","appendRoot","set","div","jsx","jsxs","DialogComponent","dialogs","addGets","current","setCurrent","useState","visible","setVisible","closeDialogRef","useRef","nextDialogRef","hasAddedUser","userId","useUserId","currentDialog","close","next","prev","useEffect","handleClose","__async","handleButtonClick","eventType","closeFn","nextFn","mainReturn","AnimatePresence","motion","btn","idx","root","createPortal","Fragment","jsx","Dialog","dialogs","addGets","appendRoot","DialogComponent","useEffect","motion","AnimatePresence","createPortal","jsx","jsxs","AlertComponent","renderAlert","removeAlert","alerts","useAlert","useEffect","alert","timer","mainReturn","AnimatePresence","item","index","motion","root","createPortal","jsx","Alert","appendRoot","AlertComponent"]}