@diffsome/sdk 3.2.8 → 3.3.0

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.
package/dist/index.js CHANGED
@@ -1705,6 +1705,330 @@ var SiteResource = class {
1705
1705
  }
1706
1706
  };
1707
1707
 
1708
+ // src/resources/chat.ts
1709
+ var ChatResource = class {
1710
+ constructor(http) {
1711
+ this.http = http;
1712
+ this.lastMessageIds = /* @__PURE__ */ new Map();
1713
+ this.visitorId = null;
1714
+ this.reverbConfig = null;
1715
+ this.websocket = null;
1716
+ this.subscribedChannels = /* @__PURE__ */ new Set();
1717
+ if (typeof localStorage !== "undefined") {
1718
+ this.visitorId = localStorage.getItem("diffsome_visitor_id");
1719
+ }
1720
+ }
1721
+ /**
1722
+ * Configure WebSocket connection (Laravel Reverb)
1723
+ */
1724
+ configureWebSocket(config) {
1725
+ this.reverbConfig = config;
1726
+ }
1727
+ /**
1728
+ * Start a new chat conversation
1729
+ */
1730
+ async start(data = {}) {
1731
+ const response = await this.http.post("/chat/conversations", data);
1732
+ this.visitorId = response.visitor_id;
1733
+ if (typeof localStorage !== "undefined") {
1734
+ localStorage.setItem("diffsome_visitor_id", this.visitorId);
1735
+ }
1736
+ return response;
1737
+ }
1738
+ /**
1739
+ * Get list of conversations
1740
+ */
1741
+ async list(params) {
1742
+ return this.http.request("/chat/conversations", {
1743
+ method: "GET",
1744
+ params,
1745
+ headers: this.getVisitorHeader()
1746
+ });
1747
+ }
1748
+ /**
1749
+ * Get conversation details
1750
+ */
1751
+ async get(conversationId) {
1752
+ return this.http.request(
1753
+ `/chat/conversations/${conversationId}`,
1754
+ {
1755
+ method: "GET",
1756
+ headers: this.getVisitorHeader()
1757
+ }
1758
+ );
1759
+ }
1760
+ /**
1761
+ * Send a message
1762
+ */
1763
+ async send(conversationId, data) {
1764
+ return this.http.request(
1765
+ `/chat/conversations/${conversationId}/messages`,
1766
+ {
1767
+ method: "POST",
1768
+ body: data,
1769
+ headers: this.getVisitorHeader()
1770
+ }
1771
+ );
1772
+ }
1773
+ /**
1774
+ * Get messages for a conversation
1775
+ */
1776
+ async getMessages(conversationId, params) {
1777
+ return this.http.request(
1778
+ `/chat/conversations/${conversationId}/messages`,
1779
+ {
1780
+ method: "GET",
1781
+ params,
1782
+ headers: this.getVisitorHeader()
1783
+ }
1784
+ );
1785
+ }
1786
+ /**
1787
+ * Poll for new messages (fallback when WebSocket not available)
1788
+ */
1789
+ async poll(conversationId, lastMessageId) {
1790
+ return this.http.request(
1791
+ `/chat/conversations/${conversationId}/poll`,
1792
+ {
1793
+ method: "GET",
1794
+ params: { last_id: lastMessageId },
1795
+ headers: this.getVisitorHeader()
1796
+ }
1797
+ );
1798
+ }
1799
+ /**
1800
+ * Close conversation
1801
+ */
1802
+ async close(conversationId) {
1803
+ await this.http.request(
1804
+ `/chat/conversations/${conversationId}/close`,
1805
+ {
1806
+ method: "POST",
1807
+ body: {},
1808
+ headers: this.getVisitorHeader()
1809
+ }
1810
+ );
1811
+ }
1812
+ /**
1813
+ * Send typing indicator
1814
+ */
1815
+ async sendTyping(conversationId) {
1816
+ await this.http.request(
1817
+ `/chat/conversations/${conversationId}/typing`,
1818
+ {
1819
+ method: "POST",
1820
+ body: {},
1821
+ headers: this.getVisitorHeader()
1822
+ }
1823
+ );
1824
+ }
1825
+ /**
1826
+ * Check agent availability
1827
+ */
1828
+ async checkAvailability() {
1829
+ return this.http.get("/chat/availability");
1830
+ }
1831
+ /**
1832
+ * Connect to a conversation with real-time updates
1833
+ * Uses WebSocket if configured, falls back to polling
1834
+ */
1835
+ connect(conversationId) {
1836
+ const messageListeners = [];
1837
+ const statusListeners = [];
1838
+ const typingListeners = [];
1839
+ let pollingActive = false;
1840
+ let pollingTimeout = null;
1841
+ let wsChannel = null;
1842
+ const connectWebSocket = async () => {
1843
+ if (!this.reverbConfig) {
1844
+ startPolling();
1845
+ return;
1846
+ }
1847
+ try {
1848
+ const channelName = `private-chat.conversation.${conversationId}`;
1849
+ const authResponse = await this.http.request(
1850
+ "/broadcasting/auth",
1851
+ {
1852
+ method: "POST",
1853
+ body: {
1854
+ socket_id: this.generateSocketId(),
1855
+ channel_name: channelName
1856
+ },
1857
+ headers: this.getVisitorHeader()
1858
+ }
1859
+ );
1860
+ const { host, port = 443, key, scheme = "wss" } = this.reverbConfig;
1861
+ const wsUrl = `${scheme}://${host}:${port}/app/${key}`;
1862
+ if (!this.websocket || this.websocket.readyState !== WebSocket.OPEN) {
1863
+ this.websocket = new WebSocket(wsUrl);
1864
+ this.websocket.onopen = () => {
1865
+ console.log("WebSocket connected");
1866
+ subscribeToChannel(channelName, authResponse.auth);
1867
+ };
1868
+ this.websocket.onmessage = (event) => {
1869
+ const data = JSON.parse(event.data);
1870
+ handleWebSocketMessage(data);
1871
+ };
1872
+ this.websocket.onerror = (error) => {
1873
+ console.error("WebSocket error:", error);
1874
+ startPolling();
1875
+ };
1876
+ this.websocket.onclose = () => {
1877
+ console.log("WebSocket closed");
1878
+ this.subscribedChannels.delete(channelName);
1879
+ };
1880
+ } else {
1881
+ subscribeToChannel(channelName, authResponse.auth);
1882
+ }
1883
+ wsChannel = channelName;
1884
+ } catch (error) {
1885
+ console.error("WebSocket connection failed:", error);
1886
+ startPolling();
1887
+ }
1888
+ };
1889
+ const subscribeToChannel = (channelName, auth) => {
1890
+ if (!this.websocket || this.subscribedChannels.has(channelName)) return;
1891
+ this.websocket.send(JSON.stringify({
1892
+ event: "pusher:subscribe",
1893
+ data: {
1894
+ auth,
1895
+ channel: channelName
1896
+ }
1897
+ }));
1898
+ this.subscribedChannels.add(channelName);
1899
+ };
1900
+ const handleWebSocketMessage = (data) => {
1901
+ if (data.event === "message.sent") {
1902
+ const message = data.data;
1903
+ messageListeners.forEach((cb) => cb(message));
1904
+ this.lastMessageIds.set(conversationId, message.id);
1905
+ } else if (data.event === "conversation.updated") {
1906
+ statusListeners.forEach((cb) => cb(data.data.status));
1907
+ } else if (data.event === "typing") {
1908
+ typingListeners.forEach((cb) => cb(data.data.sender_type));
1909
+ }
1910
+ };
1911
+ const startPolling = () => {
1912
+ if (pollingActive) return;
1913
+ pollingActive = true;
1914
+ pollLoop();
1915
+ };
1916
+ const pollLoop = async () => {
1917
+ if (!pollingActive) return;
1918
+ try {
1919
+ const lastId = this.lastMessageIds.get(conversationId) || 0;
1920
+ const result = await this.poll(conversationId, lastId);
1921
+ for (const msg of result.messages) {
1922
+ if (msg.id > lastId) {
1923
+ this.lastMessageIds.set(conversationId, msg.id);
1924
+ messageListeners.forEach((cb) => cb(msg));
1925
+ }
1926
+ }
1927
+ statusListeners.forEach((cb) => cb(result.conversation_status));
1928
+ } catch (error) {
1929
+ console.error("Chat polling error:", error);
1930
+ }
1931
+ if (pollingActive) {
1932
+ pollingTimeout = setTimeout(pollLoop, 3e3);
1933
+ }
1934
+ };
1935
+ const stopPolling = () => {
1936
+ pollingActive = false;
1937
+ if (pollingTimeout) {
1938
+ clearTimeout(pollingTimeout);
1939
+ pollingTimeout = null;
1940
+ }
1941
+ };
1942
+ const disconnect = () => {
1943
+ stopPolling();
1944
+ if (wsChannel && this.websocket) {
1945
+ this.websocket.send(JSON.stringify({
1946
+ event: "pusher:unsubscribe",
1947
+ data: { channel: wsChannel }
1948
+ }));
1949
+ this.subscribedChannels.delete(wsChannel);
1950
+ }
1951
+ };
1952
+ if (this.reverbConfig) {
1953
+ connectWebSocket();
1954
+ }
1955
+ return {
1956
+ send: (content, type) => this.send(conversationId, { content, type }),
1957
+ getMessages: (params) => this.getMessages(conversationId, params),
1958
+ onMessage: (callback) => {
1959
+ messageListeners.push(callback);
1960
+ if (!this.reverbConfig) startPolling();
1961
+ return () => {
1962
+ const idx = messageListeners.indexOf(callback);
1963
+ if (idx > -1) messageListeners.splice(idx, 1);
1964
+ if (messageListeners.length === 0 && statusListeners.length === 0) {
1965
+ disconnect();
1966
+ }
1967
+ };
1968
+ },
1969
+ onStatusChange: (callback) => {
1970
+ statusListeners.push(callback);
1971
+ if (!this.reverbConfig) startPolling();
1972
+ return () => {
1973
+ const idx = statusListeners.indexOf(callback);
1974
+ if (idx > -1) statusListeners.splice(idx, 1);
1975
+ };
1976
+ },
1977
+ onTyping: (callback) => {
1978
+ typingListeners.push(callback);
1979
+ return () => {
1980
+ const idx = typingListeners.indexOf(callback);
1981
+ if (idx > -1) typingListeners.splice(idx, 1);
1982
+ };
1983
+ },
1984
+ sendTyping: () => this.sendTyping(conversationId),
1985
+ close: () => this.close(conversationId),
1986
+ disconnect,
1987
+ // Use WebSocket if available
1988
+ useWebSocket: () => connectWebSocket(),
1989
+ // Force polling mode
1990
+ usePolling: () => {
1991
+ disconnect();
1992
+ startPolling();
1993
+ }
1994
+ };
1995
+ }
1996
+ /**
1997
+ * Generate a random socket ID
1998
+ */
1999
+ generateSocketId() {
2000
+ return `${Math.random().toString(36).substring(2)}.${Math.random().toString(36).substring(2)}`;
2001
+ }
2002
+ /**
2003
+ * Get visitor ID header
2004
+ */
2005
+ getVisitorHeader() {
2006
+ return this.visitorId ? { "X-Visitor-Id": this.visitorId } : {};
2007
+ }
2008
+ /**
2009
+ * Set visitor ID manually (useful for server-side rendering)
2010
+ */
2011
+ setVisitorId(visitorId) {
2012
+ this.visitorId = visitorId;
2013
+ }
2014
+ /**
2015
+ * Get current visitor ID
2016
+ */
2017
+ getVisitorId() {
2018
+ return this.visitorId;
2019
+ }
2020
+ /**
2021
+ * Disconnect WebSocket
2022
+ */
2023
+ disconnectWebSocket() {
2024
+ if (this.websocket) {
2025
+ this.websocket.close();
2026
+ this.websocket = null;
2027
+ this.subscribedChannels.clear();
2028
+ }
2029
+ }
2030
+ };
2031
+
1708
2032
  // src/index.ts
1709
2033
  var Diffsome = class {
1710
2034
  constructor(config) {
@@ -1722,6 +2046,7 @@ var Diffsome = class {
1722
2046
  this.entities = new EntitiesResource(this.http);
1723
2047
  this.reservation = new ReservationResource(this.http);
1724
2048
  this.site = new SiteResource(this.http);
2049
+ this.chat = new ChatResource(this.http);
1725
2050
  }
1726
2051
  /**
1727
2052
  * Check if user is authenticated
package/dist/index.mjs CHANGED
@@ -1675,6 +1675,330 @@ var SiteResource = class {
1675
1675
  }
1676
1676
  };
1677
1677
 
1678
+ // src/resources/chat.ts
1679
+ var ChatResource = class {
1680
+ constructor(http) {
1681
+ this.http = http;
1682
+ this.lastMessageIds = /* @__PURE__ */ new Map();
1683
+ this.visitorId = null;
1684
+ this.reverbConfig = null;
1685
+ this.websocket = null;
1686
+ this.subscribedChannels = /* @__PURE__ */ new Set();
1687
+ if (typeof localStorage !== "undefined") {
1688
+ this.visitorId = localStorage.getItem("diffsome_visitor_id");
1689
+ }
1690
+ }
1691
+ /**
1692
+ * Configure WebSocket connection (Laravel Reverb)
1693
+ */
1694
+ configureWebSocket(config) {
1695
+ this.reverbConfig = config;
1696
+ }
1697
+ /**
1698
+ * Start a new chat conversation
1699
+ */
1700
+ async start(data = {}) {
1701
+ const response = await this.http.post("/chat/conversations", data);
1702
+ this.visitorId = response.visitor_id;
1703
+ if (typeof localStorage !== "undefined") {
1704
+ localStorage.setItem("diffsome_visitor_id", this.visitorId);
1705
+ }
1706
+ return response;
1707
+ }
1708
+ /**
1709
+ * Get list of conversations
1710
+ */
1711
+ async list(params) {
1712
+ return this.http.request("/chat/conversations", {
1713
+ method: "GET",
1714
+ params,
1715
+ headers: this.getVisitorHeader()
1716
+ });
1717
+ }
1718
+ /**
1719
+ * Get conversation details
1720
+ */
1721
+ async get(conversationId) {
1722
+ return this.http.request(
1723
+ `/chat/conversations/${conversationId}`,
1724
+ {
1725
+ method: "GET",
1726
+ headers: this.getVisitorHeader()
1727
+ }
1728
+ );
1729
+ }
1730
+ /**
1731
+ * Send a message
1732
+ */
1733
+ async send(conversationId, data) {
1734
+ return this.http.request(
1735
+ `/chat/conversations/${conversationId}/messages`,
1736
+ {
1737
+ method: "POST",
1738
+ body: data,
1739
+ headers: this.getVisitorHeader()
1740
+ }
1741
+ );
1742
+ }
1743
+ /**
1744
+ * Get messages for a conversation
1745
+ */
1746
+ async getMessages(conversationId, params) {
1747
+ return this.http.request(
1748
+ `/chat/conversations/${conversationId}/messages`,
1749
+ {
1750
+ method: "GET",
1751
+ params,
1752
+ headers: this.getVisitorHeader()
1753
+ }
1754
+ );
1755
+ }
1756
+ /**
1757
+ * Poll for new messages (fallback when WebSocket not available)
1758
+ */
1759
+ async poll(conversationId, lastMessageId) {
1760
+ return this.http.request(
1761
+ `/chat/conversations/${conversationId}/poll`,
1762
+ {
1763
+ method: "GET",
1764
+ params: { last_id: lastMessageId },
1765
+ headers: this.getVisitorHeader()
1766
+ }
1767
+ );
1768
+ }
1769
+ /**
1770
+ * Close conversation
1771
+ */
1772
+ async close(conversationId) {
1773
+ await this.http.request(
1774
+ `/chat/conversations/${conversationId}/close`,
1775
+ {
1776
+ method: "POST",
1777
+ body: {},
1778
+ headers: this.getVisitorHeader()
1779
+ }
1780
+ );
1781
+ }
1782
+ /**
1783
+ * Send typing indicator
1784
+ */
1785
+ async sendTyping(conversationId) {
1786
+ await this.http.request(
1787
+ `/chat/conversations/${conversationId}/typing`,
1788
+ {
1789
+ method: "POST",
1790
+ body: {},
1791
+ headers: this.getVisitorHeader()
1792
+ }
1793
+ );
1794
+ }
1795
+ /**
1796
+ * Check agent availability
1797
+ */
1798
+ async checkAvailability() {
1799
+ return this.http.get("/chat/availability");
1800
+ }
1801
+ /**
1802
+ * Connect to a conversation with real-time updates
1803
+ * Uses WebSocket if configured, falls back to polling
1804
+ */
1805
+ connect(conversationId) {
1806
+ const messageListeners = [];
1807
+ const statusListeners = [];
1808
+ const typingListeners = [];
1809
+ let pollingActive = false;
1810
+ let pollingTimeout = null;
1811
+ let wsChannel = null;
1812
+ const connectWebSocket = async () => {
1813
+ if (!this.reverbConfig) {
1814
+ startPolling();
1815
+ return;
1816
+ }
1817
+ try {
1818
+ const channelName = `private-chat.conversation.${conversationId}`;
1819
+ const authResponse = await this.http.request(
1820
+ "/broadcasting/auth",
1821
+ {
1822
+ method: "POST",
1823
+ body: {
1824
+ socket_id: this.generateSocketId(),
1825
+ channel_name: channelName
1826
+ },
1827
+ headers: this.getVisitorHeader()
1828
+ }
1829
+ );
1830
+ const { host, port = 443, key, scheme = "wss" } = this.reverbConfig;
1831
+ const wsUrl = `${scheme}://${host}:${port}/app/${key}`;
1832
+ if (!this.websocket || this.websocket.readyState !== WebSocket.OPEN) {
1833
+ this.websocket = new WebSocket(wsUrl);
1834
+ this.websocket.onopen = () => {
1835
+ console.log("WebSocket connected");
1836
+ subscribeToChannel(channelName, authResponse.auth);
1837
+ };
1838
+ this.websocket.onmessage = (event) => {
1839
+ const data = JSON.parse(event.data);
1840
+ handleWebSocketMessage(data);
1841
+ };
1842
+ this.websocket.onerror = (error) => {
1843
+ console.error("WebSocket error:", error);
1844
+ startPolling();
1845
+ };
1846
+ this.websocket.onclose = () => {
1847
+ console.log("WebSocket closed");
1848
+ this.subscribedChannels.delete(channelName);
1849
+ };
1850
+ } else {
1851
+ subscribeToChannel(channelName, authResponse.auth);
1852
+ }
1853
+ wsChannel = channelName;
1854
+ } catch (error) {
1855
+ console.error("WebSocket connection failed:", error);
1856
+ startPolling();
1857
+ }
1858
+ };
1859
+ const subscribeToChannel = (channelName, auth) => {
1860
+ if (!this.websocket || this.subscribedChannels.has(channelName)) return;
1861
+ this.websocket.send(JSON.stringify({
1862
+ event: "pusher:subscribe",
1863
+ data: {
1864
+ auth,
1865
+ channel: channelName
1866
+ }
1867
+ }));
1868
+ this.subscribedChannels.add(channelName);
1869
+ };
1870
+ const handleWebSocketMessage = (data) => {
1871
+ if (data.event === "message.sent") {
1872
+ const message = data.data;
1873
+ messageListeners.forEach((cb) => cb(message));
1874
+ this.lastMessageIds.set(conversationId, message.id);
1875
+ } else if (data.event === "conversation.updated") {
1876
+ statusListeners.forEach((cb) => cb(data.data.status));
1877
+ } else if (data.event === "typing") {
1878
+ typingListeners.forEach((cb) => cb(data.data.sender_type));
1879
+ }
1880
+ };
1881
+ const startPolling = () => {
1882
+ if (pollingActive) return;
1883
+ pollingActive = true;
1884
+ pollLoop();
1885
+ };
1886
+ const pollLoop = async () => {
1887
+ if (!pollingActive) return;
1888
+ try {
1889
+ const lastId = this.lastMessageIds.get(conversationId) || 0;
1890
+ const result = await this.poll(conversationId, lastId);
1891
+ for (const msg of result.messages) {
1892
+ if (msg.id > lastId) {
1893
+ this.lastMessageIds.set(conversationId, msg.id);
1894
+ messageListeners.forEach((cb) => cb(msg));
1895
+ }
1896
+ }
1897
+ statusListeners.forEach((cb) => cb(result.conversation_status));
1898
+ } catch (error) {
1899
+ console.error("Chat polling error:", error);
1900
+ }
1901
+ if (pollingActive) {
1902
+ pollingTimeout = setTimeout(pollLoop, 3e3);
1903
+ }
1904
+ };
1905
+ const stopPolling = () => {
1906
+ pollingActive = false;
1907
+ if (pollingTimeout) {
1908
+ clearTimeout(pollingTimeout);
1909
+ pollingTimeout = null;
1910
+ }
1911
+ };
1912
+ const disconnect = () => {
1913
+ stopPolling();
1914
+ if (wsChannel && this.websocket) {
1915
+ this.websocket.send(JSON.stringify({
1916
+ event: "pusher:unsubscribe",
1917
+ data: { channel: wsChannel }
1918
+ }));
1919
+ this.subscribedChannels.delete(wsChannel);
1920
+ }
1921
+ };
1922
+ if (this.reverbConfig) {
1923
+ connectWebSocket();
1924
+ }
1925
+ return {
1926
+ send: (content, type) => this.send(conversationId, { content, type }),
1927
+ getMessages: (params) => this.getMessages(conversationId, params),
1928
+ onMessage: (callback) => {
1929
+ messageListeners.push(callback);
1930
+ if (!this.reverbConfig) startPolling();
1931
+ return () => {
1932
+ const idx = messageListeners.indexOf(callback);
1933
+ if (idx > -1) messageListeners.splice(idx, 1);
1934
+ if (messageListeners.length === 0 && statusListeners.length === 0) {
1935
+ disconnect();
1936
+ }
1937
+ };
1938
+ },
1939
+ onStatusChange: (callback) => {
1940
+ statusListeners.push(callback);
1941
+ if (!this.reverbConfig) startPolling();
1942
+ return () => {
1943
+ const idx = statusListeners.indexOf(callback);
1944
+ if (idx > -1) statusListeners.splice(idx, 1);
1945
+ };
1946
+ },
1947
+ onTyping: (callback) => {
1948
+ typingListeners.push(callback);
1949
+ return () => {
1950
+ const idx = typingListeners.indexOf(callback);
1951
+ if (idx > -1) typingListeners.splice(idx, 1);
1952
+ };
1953
+ },
1954
+ sendTyping: () => this.sendTyping(conversationId),
1955
+ close: () => this.close(conversationId),
1956
+ disconnect,
1957
+ // Use WebSocket if available
1958
+ useWebSocket: () => connectWebSocket(),
1959
+ // Force polling mode
1960
+ usePolling: () => {
1961
+ disconnect();
1962
+ startPolling();
1963
+ }
1964
+ };
1965
+ }
1966
+ /**
1967
+ * Generate a random socket ID
1968
+ */
1969
+ generateSocketId() {
1970
+ return `${Math.random().toString(36).substring(2)}.${Math.random().toString(36).substring(2)}`;
1971
+ }
1972
+ /**
1973
+ * Get visitor ID header
1974
+ */
1975
+ getVisitorHeader() {
1976
+ return this.visitorId ? { "X-Visitor-Id": this.visitorId } : {};
1977
+ }
1978
+ /**
1979
+ * Set visitor ID manually (useful for server-side rendering)
1980
+ */
1981
+ setVisitorId(visitorId) {
1982
+ this.visitorId = visitorId;
1983
+ }
1984
+ /**
1985
+ * Get current visitor ID
1986
+ */
1987
+ getVisitorId() {
1988
+ return this.visitorId;
1989
+ }
1990
+ /**
1991
+ * Disconnect WebSocket
1992
+ */
1993
+ disconnectWebSocket() {
1994
+ if (this.websocket) {
1995
+ this.websocket.close();
1996
+ this.websocket = null;
1997
+ this.subscribedChannels.clear();
1998
+ }
1999
+ }
2000
+ };
2001
+
1678
2002
  // src/index.ts
1679
2003
  var Diffsome = class {
1680
2004
  constructor(config) {
@@ -1692,6 +2016,7 @@ var Diffsome = class {
1692
2016
  this.entities = new EntitiesResource(this.http);
1693
2017
  this.reservation = new ReservationResource(this.http);
1694
2018
  this.site = new SiteResource(this.http);
2019
+ this.chat = new ChatResource(this.http);
1695
2020
  }
1696
2021
  /**
1697
2022
  * Check if user is authenticated
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diffsome/sdk",
3
- "version": "3.2.8",
3
+ "version": "3.3.0",
4
4
  "description": "Diffsome SDK for JavaScript/TypeScript - Different + Awesome",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",