@gamention/pulse-elements 0.1.16 → 0.1.17

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.
@@ -26,7 +26,7 @@
26
26
  * @license
27
27
  * Copyright 2022 Google LLC
28
28
  * SPDX-License-Identifier: BSD-3-Clause
29
- */function ae({context:o,subscribe:e}){return(t,i)=>{typeof i=="object"?i.addInitializer((function(){new Be(this,{context:o,callback:s=>{t.set.call(this,s)},subscribe:e})})):t.constructor.addInitializer((s=>{new Be(s,{context:o,callback:n=>{s[i]=n},subscribe:e})}))}}var At=Object.defineProperty,_t=(o,e,t)=>e in o?At(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t,E=(o,e,t)=>_t(o,typeof e!="symbol"?e+"":e,t);const It="ws://localhost:4567";let Me=class{constructor(){E(this,"handlers",new Map)}on(e,t){this.handlers.has(e)||this.handlers.set(e,new Set);const i=this.handlers.get(e);return i.add(t),()=>i.delete(t)}off(e,t){var i;(i=this.handlers.get(e))==null||i.delete(t)}emit(e,t){var i;(i=this.handlers.get(e))==null||i.forEach(s=>s(t))}removeAll(){this.handlers.clear()}},Mt=class extends Me{constructor(e){super(),E(this,"ws",null),E(this,"endpoint"),E(this,"reconnectAttempt",0),E(this,"reconnectTimer",null),E(this,"_state","disconnected"),this.endpoint=e??It}get state(){return this._state}connect(){this.ws||(this._state="connecting",this.emit("state",this._state),this.ws=new WebSocket(this.endpoint),this.ws.addEventListener("open",()=>{this._state="connected",this.reconnectAttempt=0,this.emit("state",this._state)}),this.ws.addEventListener("message",e=>{const t=JSON.parse(e.data);this.emit("message",t)}),this.ws.addEventListener("close",()=>{this.ws=null,this._state="disconnected",this.emit("state",this._state),this.scheduleReconnect()}),this.ws.addEventListener("error",()=>{var e;(e=this.ws)==null||e.close()}))}disconnect(){var e;this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.reconnectAttempt=0,(e=this.ws)==null||e.close(),this.ws=null,this._state="disconnected",this.emit("state",this._state)}send(e){var t;((t=this.ws)==null?void 0:t.readyState)===WebSocket.OPEN&&this.ws.send(JSON.stringify(e))}scheduleReconnect(){const e=Math.min(1e3*2**this.reconnectAttempt,3e4);this.reconnectAttempt++,this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},e)}},Ot=class extends Me{constructor(){super(...arguments),E(this,"baseUrl",""),E(this,"_user",null),E(this,"_users",new Map),E(this,"_presence",new Map),E(this,"_threads",new Map),E(this,"_reactions",new Map),E(this,"_notifications",[]),E(this,"_activityLogs",[]),E(this,"_typing",new Map),E(this,"_viewports",new Map),E(this,"_selections",new Map)}get user(){return this._user}removeComment(e){for(const[t,i]of this._threads){const s=i.comments.findIndex(n=>n.id===e);if(s!==-1){i.comments.splice(s,1),i.comments.length===0&&this._threads.delete(t),this.emit("threads",this.threads);return}}}get presence(){return[...this._presence.values()]}get threads(){return[...this._threads.values()]}get notifications(){return this._notifications}get unreadCount(){return this._notifications.filter(e=>!e.read).length}get activityLogs(){return this._activityLogs}getUser(e){return this._users.get(e)}getReactions(e){return this._reactions.get(e)??[]}getTypingUsers(e){const t=this._typing.get(e);if(!t)return[];const i=Date.now(),s=[];for(const[n,r]of t)i-r<3e3&&s.push(n);return s}get viewports(){return this._viewports}getViewport(e){return this._viewports.get(e)}get selections(){return this._selections}resolveUrl(e){return!this.baseUrl||!e||e.startsWith("http://")||e.startsWith("https://")?e:`${this.baseUrl}${e}`}resolveAttachments(e){return e.map(t=>({...t,url:this.resolveUrl(t.url),thumbnailUrl:t.thumbnailUrl?this.resolveUrl(t.thumbnailUrl):void 0}))}resolveComment(e){return!e.attachments||e.attachments.length===0?e:{...e,attachments:this.resolveAttachments(e.attachments)}}resolveThread(e){return{...e,comments:e.comments.map(t=>this.resolveComment(t))}}handleMessage(e){switch(e.type){case"auth:ok":this._user=e.user,this._users.clear();for(const t of e.users)this._users.set(t.id,t);this._presence.clear();for(const t of e.presence)this._presence.set(t.user.id,t),this._users.set(t.user.id,t.user);this._users.set(e.user.id,e.user),this._threads.clear();for(const t of e.threads)this._threads.set(t.id,this.resolveThread(t));this._notifications=e.notifications,this._reactions.clear();for(const t of e.reactions){const i=this._reactions.get(t.targetId)??[];i.push(t),this._reactions.set(t.targetId,i)}this._activityLogs=[...e.activityLogs],this.emit("auth",e.user),this.emit("presence",this.presence),this.emit("threads",this.threads),this.emit("notifications",this._notifications),this.emit("reactions",null),this.emit("activity-logs",this._activityLogs);break;case"presence:join":this._presence.set(e.user.user.id,e.user),this._users.set(e.user.user.id,e.user.user),this.emit("presence",this.presence);break;case"presence:leave":this._presence.delete(e.userId),this._viewports.delete(e.userId),this._selections.delete(e.userId);for(const t of this._typing.values())t.delete(e.userId);this.emit("presence",this.presence);break;case"presence:update":{const t=this._presence.get(e.userId);t&&(t.status=e.status,this.emit("presence",this.presence));break}case"cursor:move":this.emit("cursor",{userId:e.userId,position:e.position});break;case"click:perform":this.emit("click",{userId:e.userId,position:e.position});break;case"thread:created":this._threads.set(e.thread.id,this.resolveThread(e.thread)),this.emit("threads",this.threads);break;case"comment:created":{const t=this._threads.get(e.threadId);t&&(t.comments.push(this.resolveComment(e.comment)),t.updatedAt=e.comment.createdAt,this.emit("threads",this.threads));break}case"comment:edited":{const t=this._threads.get(e.threadId);if(t){const i=t.comments.findIndex(s=>s.id===e.comment.id);i!==-1&&(t.comments[i]=this.resolveComment(e.comment)),this.emit("threads",this.threads)}break}case"comment:deleted":{const t=this._threads.get(e.threadId);t&&(t.comments=t.comments.filter(i=>i.id!==e.commentId),t.comments.length===0&&this._threads.delete(e.threadId),this.emit("threads",this.threads));break}case"thread:resolved":{const t=this._threads.get(e.threadId);t&&(t.resolved=e.resolved,this.emit("threads",this.threads));break}case"thread:deleted":this._threads.delete(e.threadId),this.emit("threads",this.threads);break;case"reaction:added":{const t=this._reactions.get(e.reaction.targetId)??[];t.push(e.reaction),this._reactions.set(e.reaction.targetId,t),this.emit("reactions",{targetId:e.reaction.targetId,reactions:t});break}case"reaction:removed":{const t=this._reactions.get(e.targetId);if(t){const i=t.filter(s=>s.id!==e.reactionId);this._reactions.set(e.targetId,i),this.emit("reactions",{targetId:e.targetId,reactions:i})}break}case"notification":this._notifications.unshift(e.notification),this.emit("notifications",this._notifications);break;case"typing:indicator":{this._typing.has(e.threadId)||this._typing.set(e.threadId,new Map),this._typing.get(e.threadId).set(e.userId,Date.now()),this.emit("typing",{threadId:e.threadId,userId:e.userId});break}case"viewport:update":{this._viewports.set(e.userId,{scrollX:e.scrollX,scrollY:e.scrollY,viewportWidth:e.viewportWidth,viewportHeight:e.viewportHeight,pageWidth:e.pageWidth,pageHeight:e.pageHeight}),this.emit("viewport",{userId:e.userId});break}case"selection:update":this._selections.set(e.userId,e.selection),this.emit("selection",{userId:e.userId,selection:e.selection});break;case"emoji:drop":this.emit("emoji-drop",{userId:e.userId,emoji:e.emoji,position:e.position});break;case"draw:stroke":this.emit("draw-stroke",{userId:e.userId,points:e.points,color:e.color,width:e.width});break;case"draw:clear":this.emit("draw-clear",{userId:e.userId});break;case"activity:logged":this._activityLogs.unshift(e.activityLog),this._activityLogs.length>100&&(this._activityLogs=this._activityLogs.slice(0,100)),this.emit("activity-logs",this._activityLogs);break;case"error":this.emit("error",e);break}}reset(){this._user=null,this._users.clear(),this._presence.clear(),this._threads.clear(),this._reactions.clear(),this._notifications=[],this._activityLogs=[],this._typing.clear(),this._viewports.clear(),this._selections.clear()}},mt=class extends Me{constructor(e){var t;super(),E(this,"state"),E(this,"connection"),E(this,"config"),E(this,"heartbeatTimer",null),E(this,"lastCursorSend",0),E(this,"pendingCursor",null),E(this,"cursorTimer",null),this.config=e,this.state=new Ot,this.state.baseUrl=(e.endpoint??"").replace(/^ws(s?):/,"http$1:").replace(/\/$/,"");const i=((t=e.endpoint)==null?void 0:t.replace(/^http/,"ws"))??void 0;this.connection=new Mt(i),this.connection.on("message",s=>{this.state.handleMessage(s),this.emit(s.type,s)}),this.connection.on("state",s=>{this.emit("connection",s),s==="connected"?(this.authenticate(),this.startHeartbeat()):s==="disconnected"&&this.stopHeartbeat()})}get connectionState(){return this.connection.state}connect(){this.connection.connect()}disconnect(){this.stopHeartbeat(),this.connection.disconnect(),this.state.reset()}authenticate(){this.send({type:"auth",apiKey:this.config.apiKey,token:this.config.token,room:this.config.room})}send(e){this.connection.send(e)}moveCursor(e){const t=Date.now();this.pendingCursor=e,t-this.lastCursorSend>=50?this.flushCursor():this.cursorTimer||(this.cursorTimer=setTimeout(()=>{this.cursorTimer=null,this.flushCursor()},50))}flushCursor(){this.pendingCursor&&(this.send({type:"cursor:move",position:this.pendingCursor}),this.lastCursorSend=Date.now(),this.pendingCursor=null)}updatePresence(e){this.send({type:"presence:update",status:e})}startHeartbeat(){this.heartbeatTimer=setInterval(()=>{this.send({type:"presence:update",status:"online"})},3e4)}stopHeartbeat(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}createThread(e,t={}){const i=crypto.randomUUID();return this.send({type:"thread:create",id:i,body:e,mentions:t.mentions??[],position:t.position??null,attachmentIds:t.attachmentIds}),i}reply(e,t,i=[],s){const n=crypto.randomUUID();return this.send({type:"comment:create",threadId:e,id:n,body:t,mentions:i,attachmentIds:s}),n}editComment(e,t,i=[]){this.send({type:"comment:edit",commentId:e,body:t,mentions:i})}deleteComment(e){this.state.removeComment(e),this.send({type:"comment:delete",commentId:e})}resolveThread(e,t=!0){this.send({type:"thread:resolve",threadId:e,resolved:t})}addReaction(e,t,i){this.send({type:"reaction:add",targetId:e,targetType:t,emoji:i})}removeReaction(e){this.send({type:"reaction:remove",reactionId:e})}markRead(e){this.send({type:"notification:read",notificationId:e})}markAllRead(){this.send({type:"notification:read-all"})}performClick(e){this.send({type:"click:perform",position:e})}sendTyping(e){this.send({type:"typing:start",threadId:e})}updateViewport(e){this.send({type:"viewport:update",...e})}updateSelection(e){this.send({type:"selection:update",selection:e})}dropEmoji(e,t){this.send({type:"emoji:drop",emoji:e,position:t})}drawStroke(e,t,i){this.send({type:"draw:stroke",points:e,color:t,width:i})}clearDrawing(){this.send({type:"draw:clear"})}async uploadFile(e){const t=(this.config.endpoint??window.location.origin).replace(/^ws(s?):/,"http$1:"),i=new FormData;i.append("file",e);const s=await fetch(`${t}/api/v1/upload`,{method:"POST",headers:{"X-Pulse-Key":this.config.apiKey,"X-Pulse-Token":this.config.token},body:i});if(!s.ok){const r=await s.json().catch(()=>({error:"Upload failed"}));throw new Error(r.error??"Upload failed")}const n=await s.json();return n.url&&!n.url.startsWith("http")&&(n.url=`${t}${n.url}`),n.thumbnailUrl&&!n.thumbnailUrl.startsWith("http")&&(n.thumbnailUrl=`${t}${n.thumbnailUrl}`),n}setAppearOffline(e){e?(this.stopHeartbeat(),this.send({type:"presence:update",status:"idle"})):(this.startHeartbeat(),this.send({type:"presence:update",status:"online"}))}};/**
29
+ */function ae({context:o,subscribe:e}){return(t,i)=>{typeof i=="object"?i.addInitializer((function(){new Be(this,{context:o,callback:s=>{t.set.call(this,s)},subscribe:e})})):t.constructor.addInitializer((s=>{new Be(s,{context:o,callback:n=>{s[i]=n},subscribe:e})}))}}var At=Object.defineProperty,_t=(o,e,t)=>e in o?At(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t,E=(o,e,t)=>_t(o,typeof e!="symbol"?e+"":e,t);const It="ws://localhost:4567";let Me=class{constructor(){E(this,"handlers",new Map)}on(e,t){this.handlers.has(e)||this.handlers.set(e,new Set);const i=this.handlers.get(e);return i.add(t),()=>i.delete(t)}off(e,t){var i;(i=this.handlers.get(e))==null||i.delete(t)}emit(e,t){var i;(i=this.handlers.get(e))==null||i.forEach(s=>s(t))}removeAll(){this.handlers.clear()}},Mt=class extends Me{constructor(e){super(),E(this,"ws",null),E(this,"endpoint"),E(this,"reconnectAttempt",0),E(this,"reconnectTimer",null),E(this,"_state","disconnected"),this.endpoint=e??It}get state(){return this._state}connect(){this.ws||(this._state="connecting",this.emit("state",this._state),this.ws=new WebSocket(this.endpoint),this.ws.addEventListener("open",()=>{this._state="connected",this.reconnectAttempt=0,this.emit("state",this._state)}),this.ws.addEventListener("message",e=>{const t=JSON.parse(e.data);this.emit("message",t)}),this.ws.addEventListener("close",()=>{this.ws=null,this._state="disconnected",this.emit("state",this._state),this.scheduleReconnect()}),this.ws.addEventListener("error",()=>{var e;(e=this.ws)==null||e.close()}))}disconnect(){var e;this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.reconnectAttempt=0,(e=this.ws)==null||e.close(),this.ws=null,this._state="disconnected",this.emit("state",this._state)}send(e){var t;((t=this.ws)==null?void 0:t.readyState)===WebSocket.OPEN&&this.ws.send(JSON.stringify(e))}scheduleReconnect(){const e=Math.min(1e3*2**this.reconnectAttempt,3e4);this.reconnectAttempt++,this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},e)}},Ot=class extends Me{constructor(){super(...arguments),E(this,"baseUrl",""),E(this,"_user",null),E(this,"_users",new Map),E(this,"_presence",new Map),E(this,"_threads",new Map),E(this,"_reactions",new Map),E(this,"_notifications",[]),E(this,"_activityLogs",[]),E(this,"_typing",new Map),E(this,"_viewports",new Map),E(this,"_selections",new Map)}get user(){return this._user}removeComment(e){for(const[t,i]of this._threads){const s=i.comments.findIndex(n=>n.id===e);if(s!==-1){i.comments.splice(s,1),i.comments.length===0&&this._threads.delete(t),this.emit("threads",this.threads);return}}}get presence(){return[...this._presence.values()]}get threads(){return[...this._threads.values()]}get notifications(){return this._notifications}get unreadCount(){return this._notifications.filter(e=>!e.read).length}markNotificationRead(e){const t=this._notifications.find(i=>i.id===e);t&&!t.read&&(t.read=!0,this.emit("notifications",this._notifications))}markAllNotificationsRead(){let e=!1;for(const t of this._notifications)t.read||(t.read=!0,e=!0);e&&this.emit("notifications",this._notifications)}get activityLogs(){return this._activityLogs}getUser(e){return this._users.get(e)}getReactions(e){return this._reactions.get(e)??[]}getTypingUsers(e){const t=this._typing.get(e);if(!t)return[];const i=Date.now(),s=[];for(const[n,r]of t)i-r<3e3&&s.push(n);return s}get viewports(){return this._viewports}getViewport(e){return this._viewports.get(e)}get selections(){return this._selections}resolveUrl(e){return!this.baseUrl||!e||e.startsWith("http://")||e.startsWith("https://")?e:`${this.baseUrl}${e}`}resolveAttachments(e){return e.map(t=>({...t,url:this.resolveUrl(t.url),thumbnailUrl:t.thumbnailUrl?this.resolveUrl(t.thumbnailUrl):void 0}))}resolveComment(e){return!e.attachments||e.attachments.length===0?e:{...e,attachments:this.resolveAttachments(e.attachments)}}resolveThread(e){return{...e,comments:e.comments.map(t=>this.resolveComment(t))}}handleMessage(e){switch(e.type){case"auth:ok":this._user=e.user,this._users.clear();for(const t of e.users)this._users.set(t.id,t);this._presence.clear();for(const t of e.presence)this._presence.set(t.user.id,t),this._users.set(t.user.id,t.user);this._users.set(e.user.id,e.user),this._threads.clear();for(const t of e.threads)this._threads.set(t.id,this.resolveThread(t));this._notifications=e.notifications,this._reactions.clear();for(const t of e.reactions){const i=this._reactions.get(t.targetId)??[];i.push(t),this._reactions.set(t.targetId,i)}this._activityLogs=[...e.activityLogs],this.emit("auth",e.user),this.emit("presence",this.presence),this.emit("threads",this.threads),this.emit("notifications",this._notifications),this.emit("reactions",null),this.emit("activity-logs",this._activityLogs);break;case"presence:join":this._presence.set(e.user.user.id,e.user),this._users.set(e.user.user.id,e.user.user),this.emit("presence",this.presence);break;case"presence:leave":this._presence.delete(e.userId),this._viewports.delete(e.userId),this._selections.delete(e.userId);for(const t of this._typing.values())t.delete(e.userId);this.emit("presence",this.presence);break;case"presence:update":{const t=this._presence.get(e.userId);t&&(t.status=e.status,this.emit("presence",this.presence));break}case"cursor:move":this.emit("cursor",{userId:e.userId,position:e.position});break;case"click:perform":this.emit("click",{userId:e.userId,position:e.position});break;case"thread:created":this._threads.set(e.thread.id,this.resolveThread(e.thread)),this.emit("threads",this.threads);break;case"comment:created":{const t=this._threads.get(e.threadId);t&&(t.comments.push(this.resolveComment(e.comment)),t.updatedAt=e.comment.createdAt,this.emit("threads",this.threads));break}case"comment:edited":{const t=this._threads.get(e.threadId);if(t){const i=t.comments.findIndex(s=>s.id===e.comment.id);i!==-1&&(t.comments[i]=this.resolveComment(e.comment)),this.emit("threads",this.threads)}break}case"comment:deleted":{const t=this._threads.get(e.threadId);t&&(t.comments=t.comments.filter(i=>i.id!==e.commentId),t.comments.length===0&&this._threads.delete(e.threadId),this.emit("threads",this.threads));break}case"thread:resolved":{const t=this._threads.get(e.threadId);t&&(t.resolved=e.resolved,this.emit("threads",this.threads));break}case"thread:deleted":this._threads.delete(e.threadId),this.emit("threads",this.threads);break;case"reaction:added":{const t=this._reactions.get(e.reaction.targetId)??[];t.push(e.reaction),this._reactions.set(e.reaction.targetId,t),this.emit("reactions",{targetId:e.reaction.targetId,reactions:t});break}case"reaction:removed":{const t=this._reactions.get(e.targetId);if(t){const i=t.filter(s=>s.id!==e.reactionId);this._reactions.set(e.targetId,i),this.emit("reactions",{targetId:e.targetId,reactions:i})}break}case"notification":this._notifications.unshift(e.notification),this.emit("notifications",this._notifications);break;case"typing:indicator":{this._typing.has(e.threadId)||this._typing.set(e.threadId,new Map),this._typing.get(e.threadId).set(e.userId,Date.now()),this.emit("typing",{threadId:e.threadId,userId:e.userId});break}case"viewport:update":{this._viewports.set(e.userId,{scrollX:e.scrollX,scrollY:e.scrollY,viewportWidth:e.viewportWidth,viewportHeight:e.viewportHeight,pageWidth:e.pageWidth,pageHeight:e.pageHeight}),this.emit("viewport",{userId:e.userId});break}case"selection:update":this._selections.set(e.userId,e.selection),this.emit("selection",{userId:e.userId,selection:e.selection});break;case"emoji:drop":this.emit("emoji-drop",{userId:e.userId,emoji:e.emoji,position:e.position});break;case"draw:stroke":this.emit("draw-stroke",{userId:e.userId,points:e.points,color:e.color,width:e.width});break;case"draw:clear":this.emit("draw-clear",{userId:e.userId});break;case"activity:logged":this._activityLogs.unshift(e.activityLog),this._activityLogs.length>100&&(this._activityLogs=this._activityLogs.slice(0,100)),this.emit("activity-logs",this._activityLogs);break;case"error":this.emit("error",e);break}}reset(){this._user=null,this._users.clear(),this._presence.clear(),this._threads.clear(),this._reactions.clear(),this._notifications=[],this._activityLogs=[],this._typing.clear(),this._viewports.clear(),this._selections.clear()}},mt=class extends Me{constructor(e){var t;super(),E(this,"state"),E(this,"connection"),E(this,"config"),E(this,"heartbeatTimer",null),E(this,"lastCursorSend",0),E(this,"pendingCursor",null),E(this,"cursorTimer",null),this.config=e,this.state=new Ot,this.state.baseUrl=(e.endpoint??"").replace(/^ws(s?):/,"http$1:").replace(/\/$/,"");const i=((t=e.endpoint)==null?void 0:t.replace(/^http/,"ws"))??void 0;this.connection=new Mt(i),this.connection.on("message",s=>{this.state.handleMessage(s),this.emit(s.type,s)}),this.connection.on("state",s=>{this.emit("connection",s),s==="connected"?(this.authenticate(),this.startHeartbeat()):s==="disconnected"&&this.stopHeartbeat()})}get connectionState(){return this.connection.state}connect(){this.connection.connect()}disconnect(){this.stopHeartbeat(),this.connection.disconnect(),this.state.reset()}authenticate(){this.send({type:"auth",apiKey:this.config.apiKey,token:this.config.token,room:this.config.room})}send(e){this.connection.send(e)}moveCursor(e){const t=Date.now();this.pendingCursor=e,t-this.lastCursorSend>=50?this.flushCursor():this.cursorTimer||(this.cursorTimer=setTimeout(()=>{this.cursorTimer=null,this.flushCursor()},50))}flushCursor(){this.pendingCursor&&(this.send({type:"cursor:move",position:this.pendingCursor}),this.lastCursorSend=Date.now(),this.pendingCursor=null)}updatePresence(e){this.send({type:"presence:update",status:e})}startHeartbeat(){this.heartbeatTimer=setInterval(()=>{this.send({type:"presence:update",status:"online"})},3e4)}stopHeartbeat(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}createThread(e,t={}){const i=crypto.randomUUID();return this.send({type:"thread:create",id:i,body:e,mentions:t.mentions??[],position:t.position??null,attachmentIds:t.attachmentIds}),i}reply(e,t,i=[],s){const n=crypto.randomUUID();return this.send({type:"comment:create",threadId:e,id:n,body:t,mentions:i,attachmentIds:s}),n}editComment(e,t,i=[]){this.send({type:"comment:edit",commentId:e,body:t,mentions:i})}deleteComment(e){this.state.removeComment(e),this.send({type:"comment:delete",commentId:e})}resolveThread(e,t=!0){this.send({type:"thread:resolve",threadId:e,resolved:t})}addReaction(e,t,i){this.send({type:"reaction:add",targetId:e,targetType:t,emoji:i})}removeReaction(e){this.send({type:"reaction:remove",reactionId:e})}markRead(e){this.state.markNotificationRead(e),this.send({type:"notification:read",notificationId:e})}markAllRead(){this.state.markAllNotificationsRead(),this.send({type:"notification:read-all"})}performClick(e){this.send({type:"click:perform",position:e})}sendTyping(e){this.send({type:"typing:start",threadId:e})}updateViewport(e){this.send({type:"viewport:update",...e})}updateSelection(e){this.send({type:"selection:update",selection:e})}dropEmoji(e,t){this.send({type:"emoji:drop",emoji:e,position:t})}drawStroke(e,t,i){this.send({type:"draw:stroke",points:e,color:t,width:i})}clearDrawing(){this.send({type:"draw:clear"})}async uploadFile(e){const t=(this.config.endpoint??window.location.origin).replace(/^ws(s?):/,"http$1:"),i=new FormData;i.append("file",e);const s=await fetch(`${t}/api/v1/upload`,{method:"POST",headers:{"X-Pulse-Key":this.config.apiKey,"X-Pulse-Token":this.config.token},body:i});if(!s.ok){const r=await s.json().catch(()=>({error:"Upload failed"}));throw new Error(r.error??"Upload failed")}const n=await s.json();return n.url&&!n.url.startsWith("http")&&(n.url=`${t}${n.url}`),n.thumbnailUrl&&!n.thumbnailUrl.startsWith("http")&&(n.thumbnailUrl=`${t}${n.thumbnailUrl}`),n}setAppearOffline(e){e?(this.stopHeartbeat(),this.send({type:"presence:update",status:"idle"})):(this.startHeartbeat(),this.send({type:"presence:update",status:"online"}))}};/**
30
30
  * @license
31
31
  * Copyright 2019 Google LLC
32
32
  * SPDX-License-Identifier: BSD-3-Clause
@@ -2547,7 +2547,7 @@
2547
2547
  min-height: 44px;
2548
2548
  }
2549
2549
  }
2550
- `];Ne([x({attribute:!1})],re.prototype,"settings",2);Ne([x()],re.prototype,"roomId",2);re=Ne([L("pulse-widget-settings-panel")],re);const me={enabled:!0,showMyCursor:!0,showOthersCursors:!0,showMyClicks:!0,showOthersClicks:!0,appearOffline:!1,showCommentPins:!0,showViewportIndicators:!0,showSelections:!0,showDrawings:!0},kt="pulse:settings:";function us(o){try{const e=localStorage.getItem(`${kt}${o}`);return e?{...me,...JSON.parse(e)}:{...me}}catch{return{...me}}}function fs(o,e){localStorage.setItem(`${kt}${o}`,JSON.stringify(e))}var ms=Object.defineProperty,gs=Object.getOwnPropertyDescriptor,j=(o,e,t,i)=>{for(var s=i>1?void 0:i?gs(e,t):e,n=o.length-1,r;n>=0;n--)(r=o[n])&&(s=(i?r(e,t,s):r(s))||s);return i&&s&&ms(e,t,s),s};let R=class extends T{constructor(){super(...arguments),this.collapsed=!1,this.activePanel=null,this.pinModeActive=!1,this.featuresDisabled=!1,this.drawModeActive=!1,this.followingUserId=null,this.display="floating",this.users=[],this.unreadCount=0}connectedCallback(){super.connectedCallback(),this.setupPresence()}disconnectedCallback(){var o,e;super.disconnectedCallback(),(o=this.unsub)==null||o.call(this),(e=this.notifUnsub)==null||e.call(this)}updated(o){var e,t;o.has("client")&&this.client&&((e=this.unsub)==null||e.call(this),(t=this.notifUnsub)==null||t.call(this),this.setupPresence())}setupPresence(){this.client&&(this.users=this.client.state.presence,this.unreadCount=this.client.state.unreadCount,this.unsub=this.client.state.on("presence",o=>{this.users=o}),this.notifUnsub=this.client.state.on("notifications",()=>{this.unreadCount=this.client.state.unreadCount}))}getInitials(o){return o.split(" ").map(e=>e[0]).join("").toUpperCase().slice(0,2)}fire(o){this.dispatchEvent(new CustomEvent("toolbar-action",{detail:o,bubbles:!0,composed:!0}))}fireFollow(o){this.dispatchEvent(new CustomEvent("toolbar-follow",{detail:o,bubbles:!0,composed:!0}))}fireToggle(){this.dispatchEvent(new CustomEvent("toolbar-toggle",{bubbles:!0,composed:!0}))}render(){const o=this.display==="inline";if(this.collapsed)return u`
2550
+ `];Ne([x({attribute:!1})],re.prototype,"settings",2);Ne([x()],re.prototype,"roomId",2);re=Ne([L("pulse-widget-settings-panel")],re);const me={enabled:!0,showMyCursor:!0,showOthersCursors:!0,showMyClicks:!0,showOthersClicks:!0,appearOffline:!1,showCommentPins:!0,showViewportIndicators:!0,showSelections:!0,showDrawings:!0},kt="pulse:settings:";function us(o){try{const e=localStorage.getItem(`${kt}${o}`);return e?{...me,...JSON.parse(e)}:{...me}}catch{return{...me}}}function fs(o,e){localStorage.setItem(`${kt}${o}`,JSON.stringify(e))}var ms=Object.defineProperty,gs=Object.getOwnPropertyDescriptor,j=(o,e,t,i)=>{for(var s=i>1?void 0:i?gs(e,t):e,n=o.length-1,r;n>=0;n--)(r=o[n])&&(s=(i?r(e,t,s):r(s))||s);return i&&s&&ms(e,t,s),s};let R=class extends T{constructor(){super(...arguments),this.collapsed=!1,this.activePanel=null,this.pinModeActive=!1,this.featuresDisabled=!1,this.drawModeActive=!1,this.followingUserId=null,this.display="floating",this.users=[],this.unreadCount=0}connectedCallback(){super.connectedCallback(),this.setupPresence()}disconnectedCallback(){var o,e,t;super.disconnectedCallback(),(o=this.unsub)==null||o.call(this),(e=this.authUnsub)==null||e.call(this),(t=this.notifUnsub)==null||t.call(this)}updated(o){var e,t,i;o.has("client")&&this.client&&((e=this.unsub)==null||e.call(this),(t=this.authUnsub)==null||t.call(this),(i=this.notifUnsub)==null||i.call(this),this.setupPresence())}setupPresence(){this.client&&(this.users=this.client.state.presence,this.unreadCount=this.client.state.unreadCount,this.unsub=this.client.state.on("presence",o=>{this.users=[...o]}),this.authUnsub=this.client.state.on("auth",()=>{this.users=this.client.state.presence,this.unreadCount=this.client.state.unreadCount}),this.notifUnsub=this.client.state.on("notifications",()=>{this.unreadCount=this.client.state.unreadCount}))}getInitials(o){return o.split(" ").map(e=>e[0]).join("").toUpperCase().slice(0,2)}fire(o){this.dispatchEvent(new CustomEvent("toolbar-action",{detail:o,bubbles:!0,composed:!0}))}fireFollow(o){this.dispatchEvent(new CustomEvent("toolbar-follow",{detail:o,bubbles:!0,composed:!0}))}fireToggle(){this.dispatchEvent(new CustomEvent("toolbar-toggle",{bubbles:!0,composed:!0}))}render(){const o=this.display==="inline";if(this.collapsed)return u`
2551
2551
  <div class="toolbar collapsed ${o?"inline":""}" @click=${this.fireToggle}>
2552
2552
  <span class="fab-icon">${C(_i,o?18:24)}</span>
2553
2553
  </div>
@@ -245,6 +245,18 @@ let De = class {
245
245
  get unreadCount() {
246
246
  return this._notifications.filter((e) => !e.read).length;
247
247
  }
248
+ /** Optimistically mark a single notification as read. */
249
+ markNotificationRead(e) {
250
+ const t = this._notifications.find((i) => i.id === e);
251
+ t && !t.read && (t.read = !0, this.emit("notifications", this._notifications));
252
+ }
253
+ /** Optimistically mark all notifications as read. */
254
+ markAllNotificationsRead() {
255
+ let e = !1;
256
+ for (const t of this._notifications)
257
+ t.read || (t.read = !0, e = !0);
258
+ e && this.emit("notifications", this._notifications);
259
+ }
248
260
  get activityLogs() {
249
261
  return this._activityLogs;
250
262
  }
@@ -514,10 +526,10 @@ let De = class {
514
526
  }
515
527
  // ── Notifications ──
516
528
  markRead(e) {
517
- this.send({ type: "notification:read", notificationId: e });
529
+ this.state.markNotificationRead(e), this.send({ type: "notification:read", notificationId: e });
518
530
  }
519
531
  markAllRead() {
520
- this.send({ type: "notification:read-all" });
532
+ this.state.markAllNotificationsRead(), this.send({ type: "notification:read-all" });
521
533
  }
522
534
  // ── Clicks ──
523
535
  performClick(e) {
@@ -575,10 +587,10 @@ let De = class {
575
587
  * Copyright 2019 Google LLC
576
588
  * SPDX-License-Identifier: BSD-3-Clause
577
589
  */
578
- const ye = globalThis, He = ye.ShadowRoot && (ye.ShadyCSS === void 0 || ye.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype, Be = Symbol(), Je = /* @__PURE__ */ new WeakMap();
590
+ const ye = globalThis, He = ye.ShadowRoot && (ye.ShadyCSS === void 0 || ye.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype, Ne = Symbol(), Je = /* @__PURE__ */ new WeakMap();
579
591
  let kt = class {
580
592
  constructor(e, t, i) {
581
- if (this._$cssResult$ = !0, i !== Be) throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");
593
+ if (this._$cssResult$ = !0, i !== Ne) throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");
582
594
  this.cssText = e, this.t = t;
583
595
  }
584
596
  get styleSheet() {
@@ -594,14 +606,14 @@ let kt = class {
594
606
  return this.cssText;
595
607
  }
596
608
  };
597
- const Bt = (n) => new kt(typeof n == "string" ? n : n + "", void 0, Be), M = (n, ...e) => {
609
+ const Nt = (n) => new kt(typeof n == "string" ? n : n + "", void 0, Ne), M = (n, ...e) => {
598
610
  const t = n.length === 1 ? n[0] : e.reduce((i, s, o) => i + ((r) => {
599
611
  if (r._$cssResult$ === !0) return r.cssText;
600
612
  if (typeof r == "number") return r;
601
613
  throw Error("Value passed to 'css' function must be a 'css' function result: " + r + ". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.");
602
614
  })(s) + n[o + 1], n[0]);
603
- return new kt(t, n, Be);
604
- }, Nt = (n, e) => {
615
+ return new kt(t, n, Ne);
616
+ }, Bt = (n, e) => {
605
617
  if (He) n.adoptedStyleSheets = e.map((t) => t instanceof CSSStyleSheet ? t : t.styleSheet);
606
618
  else for (const t of e) {
607
619
  const i = document.createElement("style"), s = ye.litNonce;
@@ -610,7 +622,7 @@ const Bt = (n) => new kt(typeof n == "string" ? n : n + "", void 0, Be), M = (n,
610
622
  }, Ze = He ? (n) => n : (n) => n instanceof CSSStyleSheet ? ((e) => {
611
623
  let t = "";
612
624
  for (const i of e.cssRules) t += i.cssText;
613
- return Bt(t);
625
+ return Nt(t);
614
626
  })(n) : n;
615
627
  /**
616
628
  * @license
@@ -645,7 +657,7 @@ const { is: Ft, defineProperty: qt, getOwnPropertyDescriptor: Vt, getOwnProperty
645
657
  }
646
658
  }
647
659
  return t;
648
- } }, Ne = (n, e) => !Ft(n, e), et = { attribute: !0, type: String, converter: ke, reflect: !1, useDefault: !1, hasChanged: Ne };
660
+ } }, Be = (n, e) => !Ft(n, e), et = { attribute: !0, type: String, converter: ke, reflect: !1, useDefault: !1, hasChanged: Be };
649
661
  Symbol.metadata ?? (Symbol.metadata = Symbol("metadata")), H.litPropertyMetadata ?? (H.litPropertyMetadata = /* @__PURE__ */ new WeakMap());
650
662
  let G = class extends HTMLElement {
651
663
  static addInitializer(e) {
@@ -731,7 +743,7 @@ let G = class extends HTMLElement {
731
743
  }
732
744
  createRenderRoot() {
733
745
  const e = this.shadowRoot ?? this.attachShadow(this.constructor.shadowRootOptions);
734
- return Nt(e, this.constructor.elementStyles), e;
746
+ return Bt(e, this.constructor.elementStyles), e;
735
747
  }
736
748
  connectedCallback() {
737
749
  var e;
@@ -774,7 +786,7 @@ let G = class extends HTMLElement {
774
786
  var r;
775
787
  if (e !== void 0) {
776
788
  const a = this.constructor;
777
- if (s === !1 && (o = this[e]), i ?? (i = a.getPropertyOptions(e)), !((i.hasChanged ?? Ne)(o, t) || i.useDefault && i.reflect && o === ((r = this._$Ej) == null ? void 0 : r.get(e)) && !this.hasAttribute(a._$Eu(e, i)))) return;
789
+ if (s === !1 && (o = this[e]), i ?? (i = a.getPropertyOptions(e)), !((i.hasChanged ?? Be)(o, t) || i.useDefault && i.reflect && o === ((r = this._$Ej) == null ? void 0 : r.get(e)) && !this.hasAttribute(a._$Eu(e, i)))) return;
778
790
  this.C(e, t, i);
779
791
  }
780
792
  this.isUpdatePending === !1 && (this._$ES = this._$EP());
@@ -857,9 +869,9 @@ G.elementStyles = [], G.shadowRootOptions = { mode: "open" }, G[ne("elementPrope
857
869
  * SPDX-License-Identifier: BSD-3-Clause
858
870
  */
859
871
  const oe = globalThis, tt = (n) => n, Ee = oe.trustedTypes, it = Ee ? Ee.createPolicy("lit-html", { createHTML: (n) => n }) : void 0, Et = "$lit$", D = `lit$${Math.random().toFixed(9).slice(2)}$`, Ct = "?" + D, Gt = `<${Ct}>`, V = document, ae = () => V.createComment(""), le = (n) => n === null || typeof n != "object" && typeof n != "function", Fe = Array.isArray, Jt = (n) => Fe(n) || typeof (n == null ? void 0 : n[Symbol.iterator]) == "function", Ie = `[
860
- \f\r]`, se = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g, st = /-->/g, nt = />/g, N = RegExp(`>|${Ie}(?:([^\\s"'>=/]+)(${Ie}*=${Ie}*(?:[^
872
+ \f\r]`, se = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g, st = /-->/g, nt = />/g, B = RegExp(`>|${Ie}(?:([^\\s"'>=/]+)(${Ie}*=${Ie}*(?:[^
861
873
  \f\r"'\`<>=]|("|')|))|$)`, "g"), ot = /'/g, rt = /"/g, Tt = /^(?:script|style|textarea|title)$/i, St = (n) => (e, ...t) => ({ _$litType$: n, strings: e, values: t }), u = St(1), Zt = St(2), W = Symbol.for("lit-noChange"), b = Symbol.for("lit-nothing"), at = /* @__PURE__ */ new WeakMap(), F = V.createTreeWalker(V, 129);
862
- function Pt(n, e) {
874
+ function At(n, e) {
863
875
  if (!Fe(n) || !n.hasOwnProperty("raw")) throw Error("invalid template strings array");
864
876
  return it !== void 0 ? it.createHTML(e) : e;
865
877
  }
@@ -869,11 +881,11 @@ const Qt = (n, e) => {
869
881
  for (let a = 0; a < t; a++) {
870
882
  const l = n[a];
871
883
  let d, c, h = -1, p = 0;
872
- for (; p < l.length && (r.lastIndex = p, c = r.exec(l), c !== null); ) p = r.lastIndex, r === se ? c[1] === "!--" ? r = st : c[1] !== void 0 ? r = nt : c[2] !== void 0 ? (Tt.test(c[2]) && (s = RegExp("</" + c[2], "g")), r = N) : c[3] !== void 0 && (r = N) : r === N ? c[0] === ">" ? (r = s ?? se, h = -1) : c[1] === void 0 ? h = -2 : (h = r.lastIndex - c[2].length, d = c[1], r = c[3] === void 0 ? N : c[3] === '"' ? rt : ot) : r === rt || r === ot ? r = N : r === st || r === nt ? r = se : (r = N, s = void 0);
873
- const m = r === N && n[a + 1].startsWith("/>") ? " " : "";
884
+ for (; p < l.length && (r.lastIndex = p, c = r.exec(l), c !== null); ) p = r.lastIndex, r === se ? c[1] === "!--" ? r = st : c[1] !== void 0 ? r = nt : c[2] !== void 0 ? (Tt.test(c[2]) && (s = RegExp("</" + c[2], "g")), r = B) : c[3] !== void 0 && (r = B) : r === B ? c[0] === ">" ? (r = s ?? se, h = -1) : c[1] === void 0 ? h = -2 : (h = r.lastIndex - c[2].length, d = c[1], r = c[3] === void 0 ? B : c[3] === '"' ? rt : ot) : r === rt || r === ot ? r = B : r === st || r === nt ? r = se : (r = B, s = void 0);
885
+ const m = r === B && n[a + 1].startsWith("/>") ? " " : "";
874
886
  o += r === se ? l + Gt : h >= 0 ? (i.push(d), l.slice(0, h) + Et + l.slice(h) + D + m) : l + D + (h === -2 ? a : m);
875
887
  }
876
- return [Pt(n, o + (n[t] || "<?>") + (e === 2 ? "</svg>" : e === 3 ? "</math>" : "")), i];
888
+ return [At(n, o + (n[t] || "<?>") + (e === 2 ? "</svg>" : e === 3 ? "</math>" : "")), i];
877
889
  };
878
890
  class ce {
879
891
  constructor({ strings: e, _$litType$: t }, i) {
@@ -980,7 +992,7 @@ class me {
980
992
  }
981
993
  $(e) {
982
994
  var o;
983
- const { values: t, _$litType$: i } = e, s = typeof i == "number" ? this._$AC(e) : (i.el === void 0 && (i.el = ce.createElement(Pt(i.h, i.h[0]), this.options)), i);
995
+ const { values: t, _$litType$: i } = e, s = typeof i == "number" ? this._$AC(e) : (i.el === void 0 && (i.el = ce.createElement(At(i.h, i.h[0]), this.options)), i);
984
996
  if (((o = this._$AH) == null ? void 0 : o._$AD) === s) this._$AH.p(t);
985
997
  else {
986
998
  const r = new ei(s, this), a = r.u(this.options);
@@ -1093,7 +1105,7 @@ const oi = (n, e, t) => {
1093
1105
  * SPDX-License-Identifier: BSD-3-Clause
1094
1106
  */
1095
1107
  const q = globalThis;
1096
- let P = class extends G {
1108
+ let A = class extends G {
1097
1109
  constructor() {
1098
1110
  super(...arguments), this.renderOptions = { host: this }, this._$Do = void 0;
1099
1111
  }
@@ -1119,9 +1131,9 @@ let P = class extends G {
1119
1131
  }
1120
1132
  };
1121
1133
  var yt;
1122
- P._$litElement$ = !0, P.finalized = !0, (yt = q.litElementHydrateSupport) == null || yt.call(q, { LitElement: P });
1134
+ A._$litElement$ = !0, A.finalized = !0, (yt = q.litElementHydrateSupport) == null || yt.call(q, { LitElement: A });
1123
1135
  const Oe = q.litElementPolyfillSupport;
1124
- Oe == null || Oe({ LitElement: P });
1136
+ Oe == null || Oe({ LitElement: A });
1125
1137
  (q.litElementVersions ?? (q.litElementVersions = [])).push("4.2.2");
1126
1138
  /**
1127
1139
  * @license
@@ -1138,7 +1150,7 @@ const L = (n) => (e, t) => {
1138
1150
  * Copyright 2017 Google LLC
1139
1151
  * SPDX-License-Identifier: BSD-3-Clause
1140
1152
  */
1141
- const ri = { attribute: !0, type: String, converter: ke, reflect: !1, hasChanged: Ne }, ai = (n = ri, e, t) => {
1153
+ const ri = { attribute: !0, type: String, converter: ke, reflect: !1, hasChanged: Be }, ai = (n = ri, e, t) => {
1142
1154
  const { kind: i, metadata: s } = t;
1143
1155
  let o = globalThis.litPropertyMetadata.get(s);
1144
1156
  if (o === void 0 && globalThis.litPropertyMetadata.set(s, o = /* @__PURE__ */ new Map()), i === "setter" && ((n = Object.create(n)).wrapped = !0), o.set(t.name, n), i === "accessor") {
@@ -1179,7 +1191,7 @@ var li = Object.defineProperty, ci = Object.getOwnPropertyDescriptor, ee = (n, e
1179
1191
  (r = n[o]) && (s = (i ? r(e, t, s) : r(s)) || s);
1180
1192
  return i && s && li(e, t, s), s;
1181
1193
  };
1182
- let X = class extends P {
1194
+ let X = class extends A {
1183
1195
  constructor() {
1184
1196
  super(...arguments), this.apiKey = "", this.token = "", this.room = "";
1185
1197
  }
@@ -1219,12 +1231,12 @@ ee([
1219
1231
  X = ee([
1220
1232
  L("pulse-provider")
1221
1233
  ], X);
1222
- var di = Object.defineProperty, hi = Object.getOwnPropertyDescriptor, Pe = (n, e, t, i) => {
1234
+ var di = Object.defineProperty, hi = Object.getOwnPropertyDescriptor, Ae = (n, e, t, i) => {
1223
1235
  for (var s = i > 1 ? void 0 : i ? hi(e, t) : e, o = n.length - 1, r; o >= 0; o--)
1224
1236
  (r = n[o]) && (s = (i ? r(e, t, s) : r(s)) || s);
1225
1237
  return i && s && di(e, t, s), s;
1226
1238
  };
1227
- let Z = class extends P {
1239
+ let Z = class extends A {
1228
1240
  constructor() {
1229
1241
  super(...arguments), this.maxVisible = 5, this.users = [];
1230
1242
  }
@@ -1372,17 +1384,17 @@ Z.styles = M`
1372
1384
  opacity: 1;
1373
1385
  }
1374
1386
  `;
1375
- Pe([
1387
+ Ae([
1376
1388
  fe({ context: Q, subscribe: !0 }),
1377
1389
  x({ attribute: !1 })
1378
1390
  ], Z.prototype, "client", 2);
1379
- Pe([
1391
+ Ae([
1380
1392
  x({ type: Number, attribute: "max-visible" })
1381
1393
  ], Z.prototype, "maxVisible", 2);
1382
- Pe([
1394
+ Ae([
1383
1395
  $()
1384
1396
  ], Z.prototype, "users", 2);
1385
- Z = Pe([
1397
+ Z = Ae([
1386
1398
  L("pulse-presence")
1387
1399
  ], Z);
1388
1400
  var pi = Object.defineProperty, ui = Object.getOwnPropertyDescriptor, qe = (n, e, t, i) => {
@@ -1390,7 +1402,7 @@ var pi = Object.defineProperty, ui = Object.getOwnPropertyDescriptor, qe = (n, e
1390
1402
  (r = n[o]) && (s = (i ? r(e, t, s) : r(s)) || s);
1391
1403
  return i && s && pi(e, t, s), s;
1392
1404
  };
1393
- let de = class extends P {
1405
+ let de = class extends A {
1394
1406
  constructor() {
1395
1407
  super(...arguments), this.cursors = /* @__PURE__ */ new Map(), this.unsubs = [], this.handleLocalCursor = (n) => {
1396
1408
  var e;
@@ -1519,7 +1531,7 @@ var fi = Object.defineProperty, mi = Object.getOwnPropertyDescriptor, ge = (n, e
1519
1531
  (r = n[o]) && (s = (i ? r(e, t, s) : r(s)) || s);
1520
1532
  return i && s && fi(e, t, s), s;
1521
1533
  };
1522
- let Y = class extends P {
1534
+ let Y = class extends A {
1523
1535
  constructor() {
1524
1536
  super(...arguments), this.showResolved = !1, this.threads = [], this.replyingTo = null;
1525
1537
  }
@@ -1883,7 +1895,7 @@ const vi = {
1883
1895
  "thread:resolved": "✅",
1884
1896
  "reaction:added": "🎉"
1885
1897
  };
1886
- let he = class extends P {
1898
+ let he = class extends A {
1887
1899
  constructor() {
1888
1900
  super(...arguments), this.notifications = [];
1889
1901
  }
@@ -2123,7 +2135,7 @@ var yi = Object.defineProperty, wi = Object.getOwnPropertyDescriptor, te = (n, e
2123
2135
  return i && s && yi(e, t, s), s;
2124
2136
  };
2125
2137
  const $i = ["👍", "👎", "❤️", "🎉", "👀", "🚀"];
2126
- let B = class extends P {
2138
+ let N = class extends A {
2127
2139
  constructor() {
2128
2140
  super(...arguments), this.targetId = "", this.targetType = "comment", this.reactions = [], this.showPicker = !1;
2129
2141
  }
@@ -2197,7 +2209,7 @@ let B = class extends P {
2197
2209
  `;
2198
2210
  }
2199
2211
  };
2200
- B.styles = M`
2212
+ N.styles = M`
2201
2213
  :host {
2202
2214
  display: inline-flex;
2203
2215
  align-items: center;
@@ -2312,22 +2324,22 @@ B.styles = M`
2312
2324
  te([
2313
2325
  fe({ context: Q, subscribe: !0 }),
2314
2326
  x({ attribute: !1 })
2315
- ], B.prototype, "client", 2);
2327
+ ], N.prototype, "client", 2);
2316
2328
  te([
2317
2329
  x({ attribute: "target-id" })
2318
- ], B.prototype, "targetId", 2);
2330
+ ], N.prototype, "targetId", 2);
2319
2331
  te([
2320
2332
  x({ attribute: "target-type" })
2321
- ], B.prototype, "targetType", 2);
2333
+ ], N.prototype, "targetType", 2);
2322
2334
  te([
2323
2335
  $()
2324
- ], B.prototype, "reactions", 2);
2336
+ ], N.prototype, "reactions", 2);
2325
2337
  te([
2326
2338
  $()
2327
- ], B.prototype, "showPicker", 2);
2328
- B = te([
2339
+ ], N.prototype, "showPicker", 2);
2340
+ N = te([
2329
2341
  L("pulse-reactions")
2330
- ], B);
2342
+ ], N);
2331
2343
  /**
2332
2344
  * @license
2333
2345
  * Copyright 2017 Google LLC
@@ -2400,7 +2412,7 @@ const Si = [
2400
2412
  * This source code is licensed under the ISC license.
2401
2413
  * See the LICENSE file in the root directory of this source tree.
2402
2414
  */
2403
- const Pi = [
2415
+ const Ai = [
2404
2416
  ["circle", { cx: "12", cy: "12", r: "10" }],
2405
2417
  ["path", { d: "M12 6v6l4 2" }]
2406
2418
  ];
@@ -2410,7 +2422,7 @@ const Pi = [
2410
2422
  * This source code is licensed under the ISC license.
2411
2423
  * See the LICENSE file in the root directory of this source tree.
2412
2424
  */
2413
- const Ai = [
2425
+ const Pi = [
2414
2426
  [
2415
2427
  "path",
2416
2428
  {
@@ -2486,7 +2498,7 @@ const Oi = [
2486
2498
  * This source code is licensed under the ISC license.
2487
2499
  * See the LICENSE file in the root directory of this source tree.
2488
2500
  */
2489
- const At = [
2501
+ const Pt = [
2490
2502
  ["path", { d: "M12 17v5" }],
2491
2503
  [
2492
2504
  "path",
@@ -2663,7 +2675,7 @@ const ie = M`
2663
2675
  width: 18px;
2664
2676
  height: 18px;
2665
2677
  }
2666
- `, Ae = M`
2678
+ `, Pe = M`
2667
2679
  .pw-scrollable::-webkit-scrollbar {
2668
2680
  width: 4px;
2669
2681
  }
@@ -2680,7 +2692,7 @@ var Di = Object.defineProperty, Hi = Object.getOwnPropertyDescriptor, We = (n, e
2680
2692
  (r = n[o]) && (s = (i ? r(e, t, s) : r(s)) || s);
2681
2693
  return i && s && Di(e, t, s), s;
2682
2694
  };
2683
- let K = class extends P {
2695
+ let K = class extends A {
2684
2696
  constructor() {
2685
2697
  super(...arguments), this.items = [], this.unsubs = [], this.counter = 0;
2686
2698
  }
@@ -2765,7 +2777,7 @@ let K = class extends P {
2765
2777
  K.styles = [
2766
2778
  ie,
2767
2779
  ve,
2768
- Ae,
2780
+ Pe,
2769
2781
  M`
2770
2782
  :host {
2771
2783
  display: block;
@@ -2900,7 +2912,7 @@ We([
2900
2912
  K = We([
2901
2913
  L("pulse-widget-activity-panel")
2902
2914
  ], K);
2903
- const Bi = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif", lt = "#6366f1", ct = "#e2e8f0", Ni = "#f8fafc", Fi = "#e2e8f0", dt = "#64748b", we = 28, qi = Array.from({ length: we }, (n, e) => 0.2 + Math.abs(Math.sin(e * 12.9898 + 78.233) * 43758.5453) % 1 * 0.8);
2915
+ const Ni = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif", lt = "#6366f1", ct = "#e2e8f0", Bi = "#f8fafc", Fi = "#e2e8f0", dt = "#64748b", we = 28, qi = Array.from({ length: we }, (n, e) => 0.2 + Math.abs(Math.sin(e * 12.9898 + 78.233) * 43758.5453) % 1 * 0.8);
2904
2916
  function ht(n) {
2905
2917
  const e = Math.max(0, Math.floor(n)), t = Math.floor(e / 60), i = e % 60;
2906
2918
  return `${t}:${i.toString().padStart(2, "0")}`;
@@ -2926,10 +2938,10 @@ class je {
2926
2938
  width: "220px",
2927
2939
  height: "44px",
2928
2940
  padding: "0 10px",
2929
- background: Ni,
2941
+ background: Bi,
2930
2942
  borderRadius: "12px",
2931
2943
  border: `1px solid ${Fi}`,
2932
- fontFamily: Bi,
2944
+ fontFamily: Ni,
2933
2945
  fontSize: "11px",
2934
2946
  color: dt,
2935
2947
  userSelect: "none",
@@ -4510,7 +4522,7 @@ var os = Object.defineProperty, rs = Object.getOwnPropertyDescriptor, U = (n, e,
4510
4522
  return i && s && os(e, t, s), s;
4511
4523
  };
4512
4524
  const as = ["👍", "👎", "❤️", "🎉", "👀", "🚀"];
4513
- let A = class extends P {
4525
+ let P = class extends A {
4514
4526
  constructor() {
4515
4527
  super(...arguments), this.highlightThreadId = null, this.threadsVersion = 0, this.replyingTo = null, this.editingCommentId = null, this.editBody = "", this.pickerOpenForComment = null, this.typingByThread = /* @__PURE__ */ new Map(), this.reactionsVersion = 0, this.typingTimers = /* @__PURE__ */ new Map(), this.lastTypingSend = /* @__PURE__ */ new Map(), this.replyAttachmentIds = [];
4516
4528
  }
@@ -4625,14 +4637,14 @@ let A = class extends P {
4625
4637
  }
4626
4638
  async handleAttachImage() {
4627
4639
  this.upload || (this.upload = new re(this.client));
4628
- const n = A.MAX_ATTACHMENTS - this.replyAttachmentIds.length;
4640
+ const n = P.MAX_ATTACHMENTS - this.replyAttachmentIds.length;
4629
4641
  if (n <= 0) return;
4630
4642
  const e = await this.upload.pickFiles("image/*", n);
4631
4643
  e.length > 0 && (this.replyAttachmentIds.push(...e.map((t) => t.id)), this.requestUpdate());
4632
4644
  }
4633
4645
  async handleRecordAudio(n) {
4634
4646
  var i;
4635
- if (this.replyAttachmentIds.length >= A.MAX_ATTACHMENTS) return;
4647
+ if (this.replyAttachmentIds.length >= P.MAX_ATTACHMENTS) return;
4636
4648
  this.upload || (this.upload = new re(this.client)), this.audioRecorder || (this.audioRecorder = new ze());
4637
4649
  const e = (i = this.shadowRoot) == null ? void 0 : i.querySelector(`[data-thread-id="${n}"]`), t = await this.audioRecorder.startRecording(e ?? document.body);
4638
4650
  if (t) {
@@ -4642,7 +4654,7 @@ let A = class extends P {
4642
4654
  }
4643
4655
  async handleRecordVideo(n) {
4644
4656
  var i;
4645
- if (this.replyAttachmentIds.length >= A.MAX_ATTACHMENTS) return;
4657
+ if (this.replyAttachmentIds.length >= P.MAX_ATTACHMENTS) return;
4646
4658
  this.upload || (this.upload = new re(this.client)), this.videoRecorder || (this.videoRecorder = new Ue());
4647
4659
  const e = (i = this.shadowRoot) == null ? void 0 : i.querySelector(`[data-thread-id="${n}"]`), t = await this.videoRecorder.startRecording(e ?? document.body);
4648
4660
  if (t) {
@@ -4825,7 +4837,7 @@ let A = class extends P {
4825
4837
  data-thread-id=${n.id}
4826
4838
  >
4827
4839
  ${n.position ? u`<div class="pin-badge">
4828
- ${C(At, 12)}
4840
+ ${C(Pt, 12)}
4829
4841
  Pinned
4830
4842
  </div>` : b}
4831
4843
  ${n.comments.map((t, i) => {
@@ -4923,10 +4935,10 @@ let A = class extends P {
4923
4935
  `;
4924
4936
  }
4925
4937
  };
4926
- A.styles = [
4938
+ P.styles = [
4927
4939
  ie,
4928
4940
  ve,
4929
- Ae,
4941
+ Pe,
4930
4942
  M`
4931
4943
  :host {
4932
4944
  display: block;
@@ -5467,37 +5479,37 @@ A.styles = [
5467
5479
  }
5468
5480
  `
5469
5481
  ];
5470
- A.MAX_ATTACHMENTS = 5;
5482
+ P.MAX_ATTACHMENTS = 5;
5471
5483
  U([
5472
5484
  x({ attribute: !1 })
5473
- ], A.prototype, "client", 2);
5485
+ ], P.prototype, "client", 2);
5474
5486
  U([
5475
5487
  x()
5476
- ], A.prototype, "highlightThreadId", 2);
5488
+ ], P.prototype, "highlightThreadId", 2);
5477
5489
  U([
5478
5490
  $()
5479
- ], A.prototype, "threadsVersion", 2);
5491
+ ], P.prototype, "threadsVersion", 2);
5480
5492
  U([
5481
5493
  $()
5482
- ], A.prototype, "replyingTo", 2);
5494
+ ], P.prototype, "replyingTo", 2);
5483
5495
  U([
5484
5496
  $()
5485
- ], A.prototype, "editingCommentId", 2);
5497
+ ], P.prototype, "editingCommentId", 2);
5486
5498
  U([
5487
5499
  $()
5488
- ], A.prototype, "editBody", 2);
5500
+ ], P.prototype, "editBody", 2);
5489
5501
  U([
5490
5502
  $()
5491
- ], A.prototype, "pickerOpenForComment", 2);
5503
+ ], P.prototype, "pickerOpenForComment", 2);
5492
5504
  U([
5493
5505
  $()
5494
- ], A.prototype, "typingByThread", 2);
5506
+ ], P.prototype, "typingByThread", 2);
5495
5507
  U([
5496
5508
  $()
5497
- ], A.prototype, "reactionsVersion", 2);
5498
- A = U([
5509
+ ], P.prototype, "reactionsVersion", 2);
5510
+ P = U([
5499
5511
  L("pulse-widget-comments-panel")
5500
- ], A);
5512
+ ], P);
5501
5513
  var ls = Object.defineProperty, cs = Object.getOwnPropertyDescriptor, Xe = (n, e, t, i) => {
5502
5514
  for (var s = i > 1 ? void 0 : i ? cs(e, t) : e, o = n.length - 1, r; o >= 0; o--)
5503
5515
  (r = n[o]) && (s = (i ? r(e, t, s) : r(s)) || s);
@@ -5516,7 +5528,7 @@ const ds = {
5516
5528
  "thread:resolved": "✅",
5517
5529
  "reaction:added": "🎉"
5518
5530
  };
5519
- let pe = class extends P {
5531
+ let pe = class extends A {
5520
5532
  constructor() {
5521
5533
  super(...arguments), this.notifications = [];
5522
5534
  }
@@ -5607,7 +5619,7 @@ let pe = class extends P {
5607
5619
  pe.styles = [
5608
5620
  ie,
5609
5621
  ve,
5610
- Ae,
5622
+ Pe,
5611
5623
  M`
5612
5624
  :host {
5613
5625
  display: block;
@@ -6205,7 +6217,7 @@ var vs = Object.defineProperty, xs = Object.getOwnPropertyDescriptor, Ye = (n, e
6205
6217
  (r = n[o]) && (s = (i ? r(e, t, s) : r(s)) || s);
6206
6218
  return i && s && vs(e, t, s), s;
6207
6219
  };
6208
- let ue = class extends P {
6220
+ let ue = class extends A {
6209
6221
  constructor() {
6210
6222
  super(...arguments), this.roomId = "";
6211
6223
  }
@@ -6294,7 +6306,7 @@ let ue = class extends P {
6294
6306
  ue.styles = [
6295
6307
  ie,
6296
6308
  ve,
6297
- Ae,
6309
+ Pe,
6298
6310
  M`
6299
6311
  :host {
6300
6312
  display: block;
@@ -6503,7 +6515,7 @@ var $s = Object.defineProperty, ks = Object.getOwnPropertyDescriptor, j = (n, e,
6503
6515
  (r = n[o]) && (s = (i ? r(e, t, s) : r(s)) || s);
6504
6516
  return i && s && $s(e, t, s), s;
6505
6517
  };
6506
- let R = class extends P {
6518
+ let R = class extends A {
6507
6519
  constructor() {
6508
6520
  super(...arguments), this.collapsed = !1, this.activePanel = null, this.pinModeActive = !1, this.featuresDisabled = !1, this.drawModeActive = !1, this.followingUserId = null, this.display = "floating", this.users = [], this.unreadCount = 0;
6509
6521
  }
@@ -6511,16 +6523,18 @@ let R = class extends P {
6511
6523
  super.connectedCallback(), this.setupPresence();
6512
6524
  }
6513
6525
  disconnectedCallback() {
6514
- var n, e;
6515
- super.disconnectedCallback(), (n = this.unsub) == null || n.call(this), (e = this.notifUnsub) == null || e.call(this);
6526
+ var n, e, t;
6527
+ super.disconnectedCallback(), (n = this.unsub) == null || n.call(this), (e = this.authUnsub) == null || e.call(this), (t = this.notifUnsub) == null || t.call(this);
6516
6528
  }
6517
6529
  updated(n) {
6518
- var e, t;
6519
- n.has("client") && this.client && ((e = this.unsub) == null || e.call(this), (t = this.notifUnsub) == null || t.call(this), this.setupPresence());
6530
+ var e, t, i;
6531
+ n.has("client") && this.client && ((e = this.unsub) == null || e.call(this), (t = this.authUnsub) == null || t.call(this), (i = this.notifUnsub) == null || i.call(this), this.setupPresence());
6520
6532
  }
6521
6533
  setupPresence() {
6522
6534
  this.client && (this.users = this.client.state.presence, this.unreadCount = this.client.state.unreadCount, this.unsub = this.client.state.on("presence", (n) => {
6523
- this.users = n;
6535
+ this.users = [...n];
6536
+ }), this.authUnsub = this.client.state.on("auth", () => {
6537
+ this.users = this.client.state.presence, this.unreadCount = this.client.state.unreadCount;
6524
6538
  }), this.notifUnsub = this.client.state.on("notifications", () => {
6525
6539
  this.unreadCount = this.client.state.unreadCount;
6526
6540
  }));
@@ -6592,7 +6606,7 @@ let R = class extends P {
6592
6606
  ?disabled=${this.featuresDisabled}
6593
6607
  style="${this.featuresDisabled ? "opacity:0.35;pointer-events:none" : ""}"
6594
6608
  >
6595
- ${C(At)}
6609
+ ${C(Pt)}
6596
6610
  </button>
6597
6611
 
6598
6612
  <!-- View comments -->
@@ -6603,7 +6617,7 @@ let R = class extends P {
6603
6617
  ?disabled=${this.featuresDisabled}
6604
6618
  style="${this.featuresDisabled ? "opacity:0.35;pointer-events:none" : ""}"
6605
6619
  >
6606
- ${C(Ai)}
6620
+ ${C(Pi)}
6607
6621
  </button>
6608
6622
 
6609
6623
  <!-- Activity feed -->
@@ -6614,7 +6628,7 @@ let R = class extends P {
6614
6628
  ?disabled=${this.featuresDisabled}
6615
6629
  style="${this.featuresDisabled ? "opacity:0.35;pointer-events:none" : ""}"
6616
6630
  >
6617
- ${C(Pi)}
6631
+ ${C(Ai)}
6618
6632
  </button>
6619
6633
 
6620
6634
  <!-- Draw mode -->
@@ -6994,7 +7008,7 @@ var Cs = Object.defineProperty, Ts = Object.getOwnPropertyDescriptor, _ = (n, e,
6994
7008
  (r = n[o]) && (s = (i ? r(e, t, s) : r(s)) || s);
6995
7009
  return i && s && Cs(e, t, s), s;
6996
7010
  };
6997
- let T = class extends P {
7011
+ let T = class extends A {
6998
7012
  constructor() {
6999
7013
  super(...arguments), this.apiKey = "", this.token = "", this.room = "", this.position = "bottom-right", this.display = "floating", this.collapsed = !0, this.activePanel = null, this.pinModeActive = !1, this.highlightThreadId = null, this.settings = { ...$e }, this.followingUserId = null, this.drawModeActive = !1, this.connectionState = "disconnected", this.showConnectedFlash = !1, this.unsubs = [], this.clientConfigKey = "", this._isFollowScrolling = !1, this._viewportThrottleTimer = null, this._selectionThrottleTimer = null, this._connectedFlashTimer = null, this._wasDisconnected = !1, this.handleScroll = () => {
7000
7014
  !this.settings.enabled || !this.client || this._isFollowScrolling || (this.followingUserId && (this.followingUserId = null), !this._viewportThrottleTimer && (this._viewportThrottleTimer = setTimeout(() => {
@@ -7499,6 +7513,6 @@ export {
7499
7513
  he as PulseNotifications,
7500
7514
  Z as PulsePresence,
7501
7515
  X as PulseProvider,
7502
- B as PulseReactions,
7516
+ N as PulseReactions,
7503
7517
  T as PulseWidget
7504
7518
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gamention/pulse-elements",
3
- "version": "0.1.16",
3
+ "version": "0.1.17",
4
4
  "description": "Drop-in web components for real-time collaboration — comments, cursors, presence, drawing, and more",
5
5
  "type": "module",
6
6
  "main": "./dist/pulse-elements.cjs",
@@ -41,7 +41,7 @@
41
41
  "@lit/context": "^1.1.0",
42
42
  "lit": "^3.2.0",
43
43
  "lucide": "^0.577.0",
44
- "@gamention/pulse-core": "0.1.12",
44
+ "@gamention/pulse-core": "0.1.13",
45
45
  "@gamention/pulse-shared": "0.1.10"
46
46
  },
47
47
  "devDependencies": {