@knocklabs/client
Advanced tools
Comparing version 0.9.4 to 0.10.0
# Changelog | ||
## 0.10.0 | ||
### Minor Changes | ||
- 8bdc75b: Added a new MessageClient to access message api's independently from the Feed. | ||
## 0.9.4 | ||
@@ -4,0 +10,0 @@ |
@@ -1,2 +0,2 @@ | ||
"use strict";var _=Object.defineProperty;var k=(m,e,t)=>e in m?_(m,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):m[e]=t;var u=(m,e,t)=>(k(m,typeof e!="symbol"?e+"":e,t),t);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const S=require("eventemitter2"),f=require("../../networkStatus.js"),p=require("./store.js"),g={archived:"exclude"},v=2e3;class y{constructor(e,t,s){u(this,"userFeedId");u(this,"channel");u(this,"broadcaster");u(this,"defaultOptions");u(this,"broadcastChannel");u(this,"disconnectTimer",null);u(this,"hasSubscribedToRealTimeUpdates",!1);u(this,"store");this.knock=e,this.feedId=t,this.feedId=t,this.userFeedId=this.buildUserFeedId(),this.store=p.default(),this.broadcaster=new S({wildcard:!0,delimiter:"."}),this.defaultOptions={...g,...s},this.knock.log(`[Feed] Initialized a feed on channel ${t}`),this.initializeRealtimeConnection(),this.setupBroadcastChannel()}reinitialize(){this.userFeedId=this.buildUserFeedId(),this.initializeRealtimeConnection(),this.setupBroadcastChannel()}teardown(){this.knock.log("[Feed] Tearing down feed instance"),this.channel&&(this.channel.leave(),this.channel.off("new-message")),this.disconnectTimer&&(clearTimeout(this.disconnectTimer),this.disconnectTimer=null),this.broadcastChannel&&this.broadcastChannel.close()}dispose(){this.knock.log("[Feed] Disposing of feed instance"),this.teardown(),this.broadcaster.removeAllListeners(),this.knock.feeds.removeInstance(this)}listenForUpdates(){this.knock.log("[Feed] Connecting to real-time service"),this.hasSubscribedToRealTimeUpdates=!0;const e=this.knock.client().socket;e&&!e.isConnected()&&e.connect(),this.channel&&["closed","errored"].includes(this.channel.state)&&this.channel.join()}on(e,t){this.broadcaster.on(e,t)}off(e,t){this.broadcaster.off(e,t)}getState(){return this.store.getState()}async markAsSeen(e){const t=new Date().toISOString();return this.optimisticallyPerformStatusUpdate(e,"seen",{seen_at:t},"unseen_count"),this.makeStatusUpdate(e,"seen")}async markAllAsSeen(){const{getState:e,setState:t}=this.store,{metadata:s,items:a}=e();if(this.defaultOptions.status==="unseen")t(i=>i.resetStore({...s,total_count:0,unseen_count:0}));else{t(o=>o.setMetadata({...s,unseen_count:0}));const i={seen_at:new Date().toISOString()},l=a.map(o=>o.id);t(o=>o.setItemAttrs(l,i))}const n=await this.makeBulkStatusUpdate("seen");return this.broadcaster.emit("items:all_seen",{items:a}),this.broadcastOverChannel("items:all_seen",{items:a}),n}async markAsUnseen(e){return this.optimisticallyPerformStatusUpdate(e,"unseen",{seen_at:null},"unseen_count"),this.makeStatusUpdate(e,"unseen")}async markAsRead(e){const t=new Date().toISOString();return this.optimisticallyPerformStatusUpdate(e,"read",{read_at:t},"unread_count"),this.makeStatusUpdate(e,"read")}async markAllAsRead(){const{getState:e,setState:t}=this.store,{metadata:s,items:a}=e();if(this.defaultOptions.status==="unread")t(i=>i.resetStore({...s,total_count:0,unread_count:0}));else{t(o=>o.setMetadata({...s,unread_count:0}));const i={read_at:new Date().toISOString()},l=a.map(o=>o.id);t(o=>o.setItemAttrs(l,i))}const n=await this.makeBulkStatusUpdate("read");return this.broadcaster.emit("items:all_read",{items:a}),this.broadcastOverChannel("items:all_read",{items:a}),n}async markAsUnread(e){return this.optimisticallyPerformStatusUpdate(e,"unread",{read_at:null},"unread_count"),this.makeStatusUpdate(e,"unread")}async markAsInteracted(e){const t=new Date().toISOString();return this.optimisticallyPerformStatusUpdate(e,"interacted",{read_at:t,interacted_at:t},"unread_count"),this.makeStatusUpdate(e,"interacted")}async markAsArchived(e){const{getState:t,setState:s}=this.store,a=t(),r=this.defaultOptions.archived==="exclude",n=Array.isArray(e)?e:[e],i=n.map(l=>l.id);if(r){const l=n.filter(c=>!c.seen_at).length,o=n.filter(c=>!c.read_at).length,d={...a.metadata,total_count:a.metadata.total_count-n.length,unseen_count:a.metadata.unseen_count-l,unread_count:a.metadata.unread_count-o},h=a.items.filter(c=>!i.includes(c.id));s(c=>c.setResult({entries:h,meta:d,page_info:c.pageInfo}))}else a.setItemAttrs(i,{archived_at:new Date().toISOString()});return this.makeStatusUpdate(e,"archived")}async markAllAsArchived(){const{setState:e,getState:t}=this.store,{items:s}=t(),a=this.defaultOptions.archived==="exclude";e(a?n=>n.resetStore():n=>{const i=s.map(l=>l.id);n.setItemAttrs(i,{archived_at:new Date().toISOString()})});const r=await this.makeBulkStatusUpdate("archive");return this.broadcaster.emit("items:all_archived",{items:s}),this.broadcastOverChannel("items:all_archived",{items:s}),r}async markAsUnarchived(e){return this.optimisticallyPerformStatusUpdate(e,"unarchived",{archived_at:null}),this.makeStatusUpdate(e,"unarchived")}async fetch(e={}){const{setState:t,getState:s}=this.store,{networkStatus:a}=s();if(f.isRequestInFlight(a))return;t(d=>d.setNetworkStatus(e.__loadingType??f.NetworkStatus.loading));const r={...this.defaultOptions,...e,__loadingType:void 0,__fetchSource:void 0,__experimentalCrossBrowserUpdates:void 0,auto_manage_socket_connection:void 0,auto_manage_socket_connection_delay:void 0},n=await this.knock.client().makeRequest({method:"GET",url:`/v1/users/${this.knock.userId}/feeds/${this.feedId}`,params:r});if(n.statusCode==="error"||!n.body)return t(d=>d.setNetworkStatus(f.NetworkStatus.error)),{status:n.statusCode,data:n.error||n.body};const i={entries:n.body.entries,meta:n.body.meta,page_info:n.body.page_info};if(e.before){const d={shouldSetPage:!1,shouldAppend:!0};t(h=>h.setResult(i,d))}else if(e.after){const d={shouldSetPage:!0,shouldAppend:!0};t(h=>h.setResult(i,d))}else t(d=>d.setResult(i));this.broadcast("messages.new",i);const l=e.__fetchSource==="socket"?"items.received.realtime":"items.received.page",o={items:i.entries,metadata:i.meta,event:l};return this.broadcast(o.event,o),{data:i,status:n.statusCode}}async fetchNextPage(){const{getState:e}=this.store,{pageInfo:t}=e();t.after&&this.fetch({after:t.after,__loadingType:f.NetworkStatus.fetchMore})}broadcast(e,t){this.broadcaster.emit(e,t)}async onNewMessageReceived({metadata:e}){this.knock.log("[Feed] Received new real-time message");const{getState:t,setState:s}=this.store,{items:a}=t(),r=a[0];s(n=>n.setMetadata(e)),this.fetch({before:r==null?void 0:r.__cursor,__fetchSource:"socket"})}buildUserFeedId(){return`${this.feedId}:${this.knock.userId}`}optimisticallyPerformStatusUpdate(e,t,s,a){const{getState:r,setState:n}=this.store,i=Array.isArray(e)?e:[e],l=i.map(o=>o.id);if(a){const{metadata:o}=r(),d=i.filter(c=>{switch(t){case"seen":return c.seen_at===null;case"unseen":return c.seen_at!==null;case"read":case"interacted":return c.read_at===null;case"unread":return c.read_at!==null;default:return!0}}),h=t.startsWith("un")?d.length:-d.length;n(c=>c.setMetadata({...o,[a]:Math.max(0,o[a]+h)}))}n(o=>o.setItemAttrs(l,s))}async makeStatusUpdate(e,t){const s=Array.isArray(e)?e:[e],a=s.map(n=>n.id),r=await this.knock.client().makeRequest({method:"POST",url:`/v1/messages/batch/${t}`,data:{message_ids:a}});return this.broadcaster.emit(`items.${t}`,{items:s}),this.broadcaster.emit(`items:${t}`,{items:s}),this.broadcastOverChannel(`items:${t}`,{items:s}),r}async makeBulkStatusUpdate(e){const t={user_ids:[this.knock.userId],engagement_status:this.defaultOptions.status!=="all"?this.defaultOptions.status:void 0,archived:this.defaultOptions.archived,has_tenant:this.defaultOptions.has_tenant,tenants:this.defaultOptions.tenant?[this.defaultOptions.tenant]:void 0};return await this.knock.client().makeRequest({method:"POST",url:`/v1/channels/${this.feedId}/messages/bulk/${e}`,data:t})}setupBroadcastChannel(){this.broadcastChannel=typeof self<"u"&&"BroadcastChannel"in self?new BroadcastChannel(`knock:feed:${this.userFeedId}`):null,this.broadcastChannel&&this.defaultOptions.__experimentalCrossBrowserUpdates===!0&&(this.broadcastChannel.onmessage=e=>{switch(e.data.type){case"items:archived":case"items:unarchived":case"items:seen":case"items:unseen":case"items:read":case"items:unread":case"items:all_read":case"items:all_seen":case"items:all_archived":return this.fetch();default:return null}})}broadcastOverChannel(e,t){if(this.broadcastChannel)try{const s=JSON.parse(JSON.stringify(t));this.broadcastChannel.postMessage({type:e,payload:s})}catch(s){console.warn(`Could not broadcast ${e}, got error: ${s}`)}}initializeRealtimeConnection(){const{socket:e}=this.knock.client();e&&(this.channel=e.channel(`feeds:${this.userFeedId}`,this.defaultOptions),this.channel.on("new-message",t=>this.onNewMessageReceived(t)),this.defaultOptions.auto_manage_socket_connection&&this.setupAutoSocketManager(this.defaultOptions.auto_manage_socket_connection_delay),this.hasSubscribedToRealTimeUpdates&&(e.isConnected()||e.connect(),this.channel.join()))}setupAutoSocketManager(e){const t=e??v;document.addEventListener("visibilitychange",()=>{var a;const s=this.knock.client();document.visibilityState==="hidden"?this.disconnectTimer=setTimeout(()=>{var r;(r=s.socket)==null||r.disconnect(),this.disconnectTimer=null},t):document.visibilityState==="visible"&&(this.disconnectTimer&&(clearTimeout(this.disconnectTimer),this.disconnectTimer=null),(a=s.socket)!=null&&a.isConnected()||this.initializeRealtimeConnection())})}}exports.default=y; | ||
"use strict";var p=Object.defineProperty;var _=(m,e,t)=>e in m?p(m,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):m[e]=t;var u=(m,e,t)=>(_(m,typeof e!="symbol"?e+"":e,t),t);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const S=require("eventemitter2"),f=require("../../networkStatus.js"),k=require("./store.js"),g={archived:"exclude"},v=2e3;class y{constructor(e,t,s){u(this,"userFeedId");u(this,"channel");u(this,"broadcaster");u(this,"defaultOptions");u(this,"broadcastChannel");u(this,"disconnectTimer",null);u(this,"hasSubscribedToRealTimeUpdates",!1);u(this,"store");this.knock=e,this.feedId=t,this.feedId=t,this.userFeedId=this.buildUserFeedId(),this.store=k.default(),this.broadcaster=new S({wildcard:!0,delimiter:"."}),this.defaultOptions={...g,...s},this.knock.log(`[Feed] Initialized a feed on channel ${t}`),this.initializeRealtimeConnection(),this.setupBroadcastChannel()}reinitialize(){this.userFeedId=this.buildUserFeedId(),this.initializeRealtimeConnection(),this.setupBroadcastChannel()}teardown(){this.knock.log("[Feed] Tearing down feed instance"),this.channel&&(this.channel.leave(),this.channel.off("new-message")),this.disconnectTimer&&(clearTimeout(this.disconnectTimer),this.disconnectTimer=null),this.broadcastChannel&&this.broadcastChannel.close()}dispose(){this.knock.log("[Feed] Disposing of feed instance"),this.teardown(),this.broadcaster.removeAllListeners(),this.knock.feeds.removeInstance(this)}listenForUpdates(){this.knock.log("[Feed] Connecting to real-time service"),this.hasSubscribedToRealTimeUpdates=!0;const e=this.knock.client().socket;e&&!e.isConnected()&&e.connect(),this.channel&&["closed","errored"].includes(this.channel.state)&&this.channel.join()}on(e,t){this.broadcaster.on(e,t)}off(e,t){this.broadcaster.off(e,t)}getState(){return this.store.getState()}async markAsSeen(e){const t=new Date().toISOString();return this.optimisticallyPerformStatusUpdate(e,"seen",{seen_at:t},"unseen_count"),this.makeStatusUpdate(e,"seen")}async markAllAsSeen(){const{getState:e,setState:t}=this.store,{metadata:s,items:a}=e();if(this.defaultOptions.status==="unseen")t(i=>i.resetStore({...s,total_count:0,unseen_count:0}));else{t(o=>o.setMetadata({...s,unseen_count:0}));const i={seen_at:new Date().toISOString()},l=a.map(o=>o.id);t(o=>o.setItemAttrs(l,i))}const n=await this.makeBulkStatusUpdate("seen");return this.broadcaster.emit("items:all_seen",{items:a}),this.broadcastOverChannel("items:all_seen",{items:a}),n}async markAsUnseen(e){return this.optimisticallyPerformStatusUpdate(e,"unseen",{seen_at:null},"unseen_count"),this.makeStatusUpdate(e,"unseen")}async markAsRead(e){const t=new Date().toISOString();return this.optimisticallyPerformStatusUpdate(e,"read",{read_at:t},"unread_count"),this.makeStatusUpdate(e,"read")}async markAllAsRead(){const{getState:e,setState:t}=this.store,{metadata:s,items:a}=e();if(this.defaultOptions.status==="unread")t(i=>i.resetStore({...s,total_count:0,unread_count:0}));else{t(o=>o.setMetadata({...s,unread_count:0}));const i={read_at:new Date().toISOString()},l=a.map(o=>o.id);t(o=>o.setItemAttrs(l,i))}const n=await this.makeBulkStatusUpdate("read");return this.broadcaster.emit("items:all_read",{items:a}),this.broadcastOverChannel("items:all_read",{items:a}),n}async markAsUnread(e){return this.optimisticallyPerformStatusUpdate(e,"unread",{read_at:null},"unread_count"),this.makeStatusUpdate(e,"unread")}async markAsInteracted(e){const t=new Date().toISOString();return this.optimisticallyPerformStatusUpdate(e,"interacted",{read_at:t,interacted_at:t},"unread_count"),this.makeStatusUpdate(e,"interacted")}async markAsArchived(e){const{getState:t,setState:s}=this.store,a=t(),r=this.defaultOptions.archived==="exclude",n=Array.isArray(e)?e:[e],i=n.map(l=>l.id);if(r){const l=n.filter(c=>!c.seen_at).length,o=n.filter(c=>!c.read_at).length,d={...a.metadata,total_count:a.metadata.total_count-n.length,unseen_count:a.metadata.unseen_count-l,unread_count:a.metadata.unread_count-o},h=a.items.filter(c=>!i.includes(c.id));s(c=>c.setResult({entries:h,meta:d,page_info:c.pageInfo}))}else a.setItemAttrs(i,{archived_at:new Date().toISOString()});return this.makeStatusUpdate(e,"archived")}async markAllAsArchived(){const{setState:e,getState:t}=this.store,{items:s}=t(),a=this.defaultOptions.archived==="exclude";e(a?n=>n.resetStore():n=>{const i=s.map(l=>l.id);n.setItemAttrs(i,{archived_at:new Date().toISOString()})});const r=await this.makeBulkStatusUpdate("archive");return this.broadcaster.emit("items:all_archived",{items:s}),this.broadcastOverChannel("items:all_archived",{items:s}),r}async markAsUnarchived(e){return this.optimisticallyPerformStatusUpdate(e,"unarchived",{archived_at:null}),this.makeStatusUpdate(e,"unarchived")}async fetch(e={}){const{setState:t,getState:s}=this.store,{networkStatus:a}=s();if(f.isRequestInFlight(a))return;t(d=>d.setNetworkStatus(e.__loadingType??f.NetworkStatus.loading));const r={...this.defaultOptions,...e,__loadingType:void 0,__fetchSource:void 0,__experimentalCrossBrowserUpdates:void 0,auto_manage_socket_connection:void 0,auto_manage_socket_connection_delay:void 0},n=await this.knock.client().makeRequest({method:"GET",url:`/v1/users/${this.knock.userId}/feeds/${this.feedId}`,params:r});if(n.statusCode==="error"||!n.body)return t(d=>d.setNetworkStatus(f.NetworkStatus.error)),{status:n.statusCode,data:n.error||n.body};const i={entries:n.body.entries,meta:n.body.meta,page_info:n.body.page_info};if(e.before){const d={shouldSetPage:!1,shouldAppend:!0};t(h=>h.setResult(i,d))}else if(e.after){const d={shouldSetPage:!0,shouldAppend:!0};t(h=>h.setResult(i,d))}else t(d=>d.setResult(i));this.broadcast("messages.new",i);const l=e.__fetchSource==="socket"?"items.received.realtime":"items.received.page",o={items:i.entries,metadata:i.meta,event:l};return this.broadcast(o.event,o),{data:i,status:n.statusCode}}async fetchNextPage(){const{getState:e}=this.store,{pageInfo:t}=e();t.after&&this.fetch({after:t.after,__loadingType:f.NetworkStatus.fetchMore})}broadcast(e,t){this.broadcaster.emit(e,t)}async onNewMessageReceived({metadata:e}){this.knock.log("[Feed] Received new real-time message");const{getState:t,setState:s}=this.store,{items:a}=t(),r=a[0];s(n=>n.setMetadata(e)),this.fetch({before:r==null?void 0:r.__cursor,__fetchSource:"socket"})}buildUserFeedId(){return`${this.feedId}:${this.knock.userId}`}optimisticallyPerformStatusUpdate(e,t,s,a){const{getState:r,setState:n}=this.store,i=Array.isArray(e)?e:[e],l=i.map(o=>o.id);if(a){const{metadata:o}=r(),d=i.filter(c=>{switch(t){case"seen":return c.seen_at===null;case"unseen":return c.seen_at!==null;case"read":case"interacted":return c.read_at===null;case"unread":return c.read_at!==null;default:return!0}}),h=t.startsWith("un")?d.length:-d.length;n(c=>c.setMetadata({...o,[a]:Math.max(0,o[a]+h)}))}n(o=>o.setItemAttrs(l,s))}async makeStatusUpdate(e,t){const s=Array.isArray(e)?e:[e],a=s.map(n=>n.id),r=await this.knock.messages.batchUpdateStatuses(a,t);return this.broadcaster.emit(`items.${t}`,{items:s}),this.broadcaster.emit(`items:${t}`,{items:s}),this.broadcastOverChannel(`items:${t}`,{items:s}),r}async makeBulkStatusUpdate(e){const t={user_ids:[this.knock.userId],engagement_status:this.defaultOptions.status!=="all"?this.defaultOptions.status:void 0,archived:this.defaultOptions.archived,has_tenant:this.defaultOptions.has_tenant,tenants:this.defaultOptions.tenant?[this.defaultOptions.tenant]:void 0};return await this.knock.messages.bulkUpdateAllStatusesInChannel({channelId:this.feedId,status:e,options:t})}setupBroadcastChannel(){this.broadcastChannel=typeof self<"u"&&"BroadcastChannel"in self?new BroadcastChannel(`knock:feed:${this.userFeedId}`):null,this.broadcastChannel&&this.defaultOptions.__experimentalCrossBrowserUpdates===!0&&(this.broadcastChannel.onmessage=e=>{switch(e.data.type){case"items:archived":case"items:unarchived":case"items:seen":case"items:unseen":case"items:read":case"items:unread":case"items:all_read":case"items:all_seen":case"items:all_archived":return this.fetch();default:return null}})}broadcastOverChannel(e,t){if(this.broadcastChannel)try{const s=JSON.parse(JSON.stringify(t));this.broadcastChannel.postMessage({type:e,payload:s})}catch(s){console.warn(`Could not broadcast ${e}, got error: ${s}`)}}initializeRealtimeConnection(){const{socket:e}=this.knock.client();e&&(this.channel=e.channel(`feeds:${this.userFeedId}`,this.defaultOptions),this.channel.on("new-message",t=>this.onNewMessageReceived(t)),this.defaultOptions.auto_manage_socket_connection&&this.setupAutoSocketManager(this.defaultOptions.auto_manage_socket_connection_delay),this.hasSubscribedToRealTimeUpdates&&(e.isConnected()||e.connect(),this.channel.join()))}setupAutoSocketManager(e){const t=e??v;document.addEventListener("visibilitychange",()=>{var a;const s=this.knock.client();document.visibilityState==="hidden"?this.disconnectTimer=setTimeout(()=>{var r;(r=s.socket)==null||r.disconnect(),this.disconnectTimer=null},t):document.visibilityState==="visible"&&(this.disconnectTimer&&(clearTimeout(this.disconnectTimer),this.disconnectTimer=null),(a=s.socket)!=null&&a.isConnected()||this.initializeRealtimeConnection())})}}exports.default=y; | ||
//# sourceMappingURL=feed.js.map |
@@ -1,6 +0,6 @@ | ||
"use strict";var h=Object.defineProperty;var c=(s,e,t)=>e in s?h(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t;var i=(s,e,t)=>(c(s,typeof e!="symbol"?e+"":e,t),t);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const l=require("jwt-decode"),d=require("./api.js"),k=require("./clients/feed/index.js"),f=require("./clients/objects/index.js"),p=require("./clients/preferences/index.js"),T=require("./clients/slack/index.js"),w=require("./clients/users/index.js"),g="https://api.knock.app";class y{constructor(e,t={}){i(this,"host");i(this,"apiClient",null);i(this,"userId");i(this,"userToken");i(this,"logLevel");i(this,"tokenExpirationTimer",null);i(this,"feeds",new k.default(this));i(this,"objects",new f.default(this));i(this,"preferences",new p.default(this));i(this,"slack",new T.default(this));i(this,"user",new w.default(this));if(this.apiKey=e,this.host=t.host||g,this.logLevel=t.logLevel,this.log("Initialized Knock instance"),this.apiKey&&this.apiKey.startsWith("sk_"))throw new Error("[Knock] You are using your secret API key on the client. Please use the public key.")}client(){return this.userId||console.warn(`[Knock] You must call authenticate(userId, userToken) first before trying to make a request. | ||
"use strict";var h=Object.defineProperty;var c=(n,e,t)=>e in n?h(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var i=(n,e,t)=>(c(n,typeof e!="symbol"?e+"":e,t),t);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const l=require("jwt-decode"),d=require("./api.js"),k=require("./clients/feed/index.js"),f=require("./clients/messages/index.js"),p=require("./clients/objects/index.js"),T=require("./clients/preferences/index.js"),w=require("./clients/slack/index.js"),g=require("./clients/users/index.js"),y="https://api.knock.app";class x{constructor(e,t={}){i(this,"host");i(this,"apiClient",null);i(this,"userId");i(this,"userToken");i(this,"logLevel");i(this,"tokenExpirationTimer",null);i(this,"feeds",new k.default(this));i(this,"objects",new p.default(this));i(this,"preferences",new T.default(this));i(this,"slack",new w.default(this));i(this,"user",new g.default(this));i(this,"messages",new f.default(this));if(this.apiKey=e,this.host=t.host||y,this.logLevel=t.logLevel,this.log("Initialized Knock instance"),this.apiKey&&this.apiKey.startsWith("sk_"))throw new Error("[Knock] You are using your secret API key on the client. Please use the public key.")}client(){return this.userId||console.warn(`[Knock] You must call authenticate(userId, userToken) first before trying to make a request. | ||
Typically you'll see this message when you're creating a feed instance before having called | ||
authenticate with a user Id and token. That means we won't know who to issue the request | ||
to Knock on behalf of. | ||
`),this.apiClient||(this.apiClient=this.createApiClient()),this.apiClient}authenticate(e,t,n){let r=!1;this.apiClient&&(this.userId!==e||this.userToken!==t)&&(this.log("userId or userToken changed; reinitializing connections"),this.feeds.teardownInstances(),this.teardown(),r=!0),this.userId=e,this.userToken=t,this.log(`Authenticated with userId ${e}`),this.userToken&&(n==null?void 0:n.onUserTokenExpiring)instanceof Function&&this.maybeScheduleUserTokenExpiration(n.onUserTokenExpiring,n.timeBeforeExpirationInMs),r&&(this.apiClient=this.createApiClient(),this.feeds.reinitializeInstances(),this.log("Reinitialized real-time connections"))}isAuthenticated(e=!1){return e?!!(this.userId&&this.userToken):!!this.userId}teardown(){var e;this.tokenExpirationTimer&&clearTimeout(this.tokenExpirationTimer),(e=this.apiClient)!=null&&e.socket&&this.apiClient.socket.isConnected()&&this.apiClient.socket.disconnect()}log(e){this.logLevel==="debug"&&console.log(`[Knock] ${e}`)}createApiClient(){return new d.default({apiKey:this.apiKey,host:this.host,userToken:this.userToken})}async maybeScheduleUserTokenExpiration(e,t=3e4){if(!this.userToken)return;const n=l.jwtDecode(this.userToken),r=(n.exp??0)*1e3,o=Date.now();if(r&&r>o){const u=r-t-o;this.tokenExpirationTimer=setTimeout(async()=>{const a=await e(this.userToken,n);typeof a=="string"&&this.authenticate(this.userId,a,{onUserTokenExpiring:e,timeBeforeExpirationInMs:t})},u)}}}exports.default=y; | ||
`),this.apiClient||(this.apiClient=this.createApiClient()),this.apiClient}authenticate(e,t,s){let r=!1;this.apiClient&&(this.userId!==e||this.userToken!==t)&&(this.log("userId or userToken changed; reinitializing connections"),this.feeds.teardownInstances(),this.teardown(),r=!0),this.userId=e,this.userToken=t,this.log(`Authenticated with userId ${e}`),this.userToken&&(s==null?void 0:s.onUserTokenExpiring)instanceof Function&&this.maybeScheduleUserTokenExpiration(s.onUserTokenExpiring,s.timeBeforeExpirationInMs),r&&(this.apiClient=this.createApiClient(),this.feeds.reinitializeInstances(),this.log("Reinitialized real-time connections"))}isAuthenticated(e=!1){return e?!!(this.userId&&this.userToken):!!this.userId}teardown(){var e;this.tokenExpirationTimer&&clearTimeout(this.tokenExpirationTimer),(e=this.apiClient)!=null&&e.socket&&this.apiClient.socket.isConnected()&&this.apiClient.socket.disconnect()}log(e){this.logLevel==="debug"&&console.log(`[Knock] ${e}`)}createApiClient(){return new d.default({apiKey:this.apiKey,host:this.host,userToken:this.userToken})}async maybeScheduleUserTokenExpiration(e,t=3e4){if(!this.userToken)return;const s=l.jwtDecode(this.userToken),r=(s.exp??0)*1e3,o=Date.now();if(r&&r>o){const u=r-t-o;this.tokenExpirationTimer=setTimeout(async()=>{const a=await e(this.userToken,s);typeof a=="string"&&this.authenticate(this.userId,a,{onUserTokenExpiring:e,timeBeforeExpirationInMs:t})},u)}}}exports.default=x; | ||
//# sourceMappingURL=knock.js.map |
@@ -5,3 +5,2 @@ import { StoreApi } from "zustand"; | ||
import { BindableFeedEvent, FeedEventCallback, FeedItemOrItems, FeedRealTimeCallback, FeedStoreState } from "./types"; | ||
export type Status = "seen" | "read" | "interacted" | "archived" | "unseen" | "unread" | "unarchived"; | ||
declare class Feed { | ||
@@ -34,12 +33,12 @@ readonly knock: Knock; | ||
getState(): FeedStoreState; | ||
markAsSeen(itemOrItems: FeedItemOrItems): Promise<import("../../api").ApiResponse>; | ||
markAllAsSeen(): Promise<import("../../api").ApiResponse>; | ||
markAsUnseen(itemOrItems: FeedItemOrItems): Promise<import("../../api").ApiResponse>; | ||
markAsRead(itemOrItems: FeedItemOrItems): Promise<import("../../api").ApiResponse>; | ||
markAllAsRead(): Promise<import("../../api").ApiResponse>; | ||
markAsUnread(itemOrItems: FeedItemOrItems): Promise<import("../../api").ApiResponse>; | ||
markAsInteracted(itemOrItems: FeedItemOrItems): Promise<import("../../api").ApiResponse>; | ||
markAsArchived(itemOrItems: FeedItemOrItems): Promise<import("../../api").ApiResponse>; | ||
markAllAsArchived(): Promise<import("../../api").ApiResponse>; | ||
markAsUnarchived(itemOrItems: FeedItemOrItems): Promise<import("../../api").ApiResponse>; | ||
markAsSeen(itemOrItems: FeedItemOrItems): Promise<import("../messages/interfaces").Message<any>[]>; | ||
markAllAsSeen(): Promise<import("../..").BulkOperation>; | ||
markAsUnseen(itemOrItems: FeedItemOrItems): Promise<import("../messages/interfaces").Message<any>[]>; | ||
markAsRead(itemOrItems: FeedItemOrItems): Promise<import("../messages/interfaces").Message<any>[]>; | ||
markAllAsRead(): Promise<import("../..").BulkOperation>; | ||
markAsUnread(itemOrItems: FeedItemOrItems): Promise<import("../messages/interfaces").Message<any>[]>; | ||
markAsInteracted(itemOrItems: FeedItemOrItems): Promise<import("../messages/interfaces").Message<any>[]>; | ||
markAsArchived(itemOrItems: FeedItemOrItems): Promise<import("../messages/interfaces").Message<any>[]>; | ||
markAllAsArchived(): Promise<import("../..").BulkOperation>; | ||
markAsUnarchived(itemOrItems: FeedItemOrItems): Promise<import("../messages/interfaces").Message<any>[]>; | ||
fetch(options?: FetchFeedOptions): Promise<{ | ||
@@ -46,0 +45,0 @@ status: "ok" | "error"; |
import { GenericData, PageInfo } from "@knocklabs/types"; | ||
import { Activity, Recipient } from "../../interfaces"; | ||
import { NetworkStatus } from "../../networkStatus"; | ||
import { NotificationSource } from "../messages/interfaces"; | ||
export interface FeedClientOptions { | ||
@@ -46,6 +47,2 @@ before?: string; | ||
} | ||
export interface NotificationSource { | ||
key: string; | ||
version_id: string; | ||
} | ||
export type ContentBlock = MarkdownContentBlock | TextContentBlock | ButtonSetContentBlock; | ||
@@ -52,0 +49,0 @@ export interface FeedItem<T = GenericData> { |
@@ -12,2 +12,5 @@ import FeedClient, { Feed } from "./clients/feed"; | ||
export * from "./clients/users"; | ||
export * from "./clients/users/interfaces"; | ||
export * from "./clients/messages"; | ||
export * from "./clients/messages/interfaces"; | ||
export * from "./networkStatus"; | ||
@@ -14,0 +17,0 @@ export default Knock; |
@@ -24,2 +24,6 @@ import { GenericData } from "@knocklabs/types"; | ||
export type Recipient = User | KnockObject; | ||
export type RecipientRef = string | { | ||
collection: string; | ||
id: string; | ||
}; | ||
export interface Activity<T = GenericData> { | ||
@@ -42,2 +46,14 @@ id: string; | ||
} | ||
export interface BulkOperation { | ||
id: string; | ||
name: string; | ||
status: "queued" | "processing" | "completed" | "failed"; | ||
processed_rows: number; | ||
estimated_total_rows: number; | ||
started_at?: string; | ||
completed_at?: string; | ||
failed_at?: string; | ||
inserted_at: string; | ||
updated_at: string; | ||
} | ||
//# sourceMappingURL=interfaces.d.ts.map |
import ApiClient from "./api"; | ||
import FeedClient from "./clients/feed"; | ||
import MessageClient from "./clients/messages"; | ||
import ObjectClient from "./clients/objects"; | ||
@@ -21,2 +22,3 @@ import Preferences from "./clients/preferences"; | ||
readonly user: UserClient; | ||
readonly messages: MessageClient; | ||
constructor(apiKey: string, options?: KnockOptions); | ||
@@ -23,0 +25,0 @@ client(): ApiClient; |
{ | ||
"name": "@knocklabs/client", | ||
"version": "0.9.4", | ||
"version": "0.10.0", | ||
"description": "The clientside library for interacting with Knock", | ||
@@ -5,0 +5,0 @@ "homepage": "https://github.com/knocklabs/javascript/tree/main/packages/client", |
@@ -7,2 +7,6 @@ import EventEmitter from "eventemitter2"; | ||
import { NetworkStatus, isRequestInFlight } from "../../networkStatus"; | ||
import { | ||
BulkUpdateMessagesInChannelProperties, | ||
MessageEngagementStatus, | ||
} from "../messages/interfaces"; | ||
@@ -28,11 +32,2 @@ import { | ||
export type Status = | ||
| "seen" | ||
| "read" | ||
| "interacted" | ||
| "archived" | ||
| "unseen" | ||
| "unread" | ||
| "unarchived"; | ||
// Default options to apply | ||
@@ -561,3 +556,3 @@ const feedClientDefaults: Pick<FeedClientOptions, "archived"> = { | ||
itemOrItems: FeedItemOrItems, | ||
type: Status, | ||
type: MessageEngagementStatus | "unread" | "unseen" | "unarchived", | ||
attrs: object, | ||
@@ -611,3 +606,6 @@ badgeCountAttr?: "unread_count" | "unseen_count", | ||
private async makeStatusUpdate(itemOrItems: FeedItemOrItems, type: Status) { | ||
private async makeStatusUpdate( | ||
itemOrItems: FeedItemOrItems, | ||
type: MessageEngagementStatus | "unread" | "unseen" | "unarchived", | ||
) { | ||
// Always treat items as a batch to use the corresponding batch endpoint | ||
@@ -617,7 +615,3 @@ const items = Array.isArray(itemOrItems) ? itemOrItems : [itemOrItems]; | ||
const result = await this.knock.client().makeRequest({ | ||
method: "POST", | ||
url: `/v1/messages/batch/${type}`, | ||
data: { message_ids: itemIds }, | ||
}); | ||
const result = await this.knock.messages.batchUpdateStatuses(itemIds, type); | ||
@@ -628,3 +622,3 @@ // Emit the event that these items had their statuses changed | ||
// Note: `items.type` format is being deprecated in favor over the `items:type` format, | ||
// Note: `items.type` format is being deprecated in favor over the `items:type` format, | ||
// but emit both formats to make it backward compatible for now. | ||
@@ -637,3 +631,5 @@ this.broadcaster.emit(`items:${type}`, { items }); | ||
private async makeBulkStatusUpdate(type: "seen" | "read" | "archive") { | ||
private async makeBulkStatusUpdate( | ||
status: BulkUpdateMessagesInChannelProperties["status"], | ||
) { | ||
// The base scope for the call should take into account all of the options currently | ||
@@ -644,3 +640,3 @@ // set on the feed, as well as being scoped for the current user. We do this so that | ||
const options = { | ||
user_ids: [this.knock.userId], | ||
user_ids: [this.knock.userId!], | ||
engagement_status: | ||
@@ -657,6 +653,6 @@ this.defaultOptions.status !== "all" | ||
return await this.knock.client().makeRequest({ | ||
method: "POST", | ||
url: `/v1/channels/${this.feedId}/messages/bulk/${type}`, | ||
data: options, | ||
return await this.knock.messages.bulkUpdateAllStatusesInChannel({ | ||
channelId: this.feedId, | ||
status, | ||
options, | ||
}); | ||
@@ -663,0 +659,0 @@ } |
@@ -5,2 +5,3 @@ import { GenericData, PageInfo } from "@knocklabs/types"; | ||
import { NetworkStatus } from "../../networkStatus"; | ||
import { NotificationSource } from "../messages/interfaces"; | ||
@@ -68,7 +69,2 @@ // Specific feed interfaces | ||
export interface NotificationSource { | ||
key: string; | ||
version_id: string; | ||
} | ||
export type ContentBlock = | ||
@@ -75,0 +71,0 @@ | MarkdownContentBlock |
@@ -13,2 +13,5 @@ import FeedClient, { Feed } from "./clients/feed"; | ||
export * from "./clients/users"; | ||
export * from "./clients/users/interfaces"; | ||
export * from "./clients/messages"; | ||
export * from "./clients/messages/interfaces"; | ||
export * from "./networkStatus"; | ||
@@ -15,0 +18,0 @@ |
@@ -30,2 +30,4 @@ import { GenericData } from "@knocklabs/types"; | ||
export type RecipientRef = string | { collection: string; id: string }; | ||
export interface Activity<T = GenericData> { | ||
@@ -54,1 +56,14 @@ id: string; | ||
} | ||
export interface BulkOperation { | ||
id: string; | ||
name: string; | ||
status: "queued" | "processing" | "completed" | "failed"; | ||
processed_rows: number; | ||
estimated_total_rows: number; | ||
started_at?: string; | ||
completed_at?: string; | ||
failed_at?: string; | ||
inserted_at: string; | ||
updated_at: string; | ||
} |
@@ -5,2 +5,3 @@ import { jwtDecode } from "jwt-decode"; | ||
import FeedClient from "./clients/feed"; | ||
import MessageClient from "./clients/messages"; | ||
import ObjectClient from "./clients/objects"; | ||
@@ -31,2 +32,3 @@ import Preferences from "./clients/preferences"; | ||
readonly user = new UserClient(this); | ||
readonly messages = new MessageClient(this); | ||
@@ -33,0 +35,0 @@ constructor( |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
328431
123
3479