@monterosa/sdk-interact-kit 0.19.0-rc.2 → 0.19.0-rc.4

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.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { getConnect as getConnect$1, login as login$1, connect, disconnect, subscribe as subscribe$1, unsubscribe as unsubscribe$1, send, ConnState, onConnected } from '@monterosa/sdk-connect-kit';
2
- import { Emitter, memoizePromise, subscribe as subscribe$2, onTick, now, checkAvailability, getItem, setItem, createError } from '@monterosa/sdk-util';
3
- import { getSdk } from '@monterosa/sdk-core';
2
+ import { Emitter, memoizePromise, subscribe as subscribe$2, onTick, now, checkAvailability, calculatePercentage, getItem, setItem, createError } from '@monterosa/sdk-util';
3
+ import { getSdk, Logger } from '@monterosa/sdk-core';
4
4
 
5
5
  /**
6
6
  * @license
@@ -72,6 +72,7 @@ var Klass;
72
72
  Klass["Feedback"] = "fb";
73
73
  Klass["Eoc"] = "eoc";
74
74
  Klass["Vote"] = "v";
75
+ Klass["SubsCounter"] = "subscounter";
75
76
  })(Klass || (Klass = {}));
76
77
  /**
77
78
  * @internal
@@ -1501,52 +1502,6 @@ class ElementImpl extends Emitter {
1501
1502
  }
1502
1503
  }
1503
1504
 
1504
- /**
1505
- * @license
1506
- * @monterosa/sdk-interact-kit
1507
- *
1508
- * Copyright © 2022 Monterosa Productions Limited. All rights reserved.
1509
- *
1510
- * More details on the license can be found at https://www.monterosa.co/sdk/license
1511
- */
1512
- const calculatePercentage = (values) => {
1513
- // Calculate sum of all votes
1514
- const sum = values.reduce((memo, value) => memo + value, 0);
1515
- // create array of hashes
1516
- const results = values.map((value, idx) => ({
1517
- idx,
1518
- votes: value,
1519
- percentage: Math.round((100 * value) / sum) || 0,
1520
- }));
1521
- // Sum them all up - this can be less, equal or greater than a 100%
1522
- let total = results.reduce((memo, { percentage }) => memo + percentage, 0);
1523
- total = total || 100;
1524
- // Calculate number of percent that we are missing or that we need to lose
1525
- let delta = 100 - total;
1526
- const sign = delta >= 0 ? 1 : -1;
1527
- // Order all options by number of votes
1528
- results.sort((a, b) => {
1529
- const result = sign * (b.votes - a.votes);
1530
- if (result !== 0) {
1531
- return result;
1532
- }
1533
- return sign * (a.idx - b.idx);
1534
- });
1535
- // If we have percents to lose then take one percent off lowest options
1536
- // If we are missing percents then add one percent to highest options
1537
- let i = 0;
1538
- while (delta !== 0) {
1539
- if (results[i].votes > 0) {
1540
- results[i].percentage += sign;
1541
- delta -= sign;
1542
- }
1543
- i++;
1544
- }
1545
- // Restore options order
1546
- results.sort((a, b) => a.idx - b.idx);
1547
- return results.map((item) => item.percentage);
1548
- };
1549
-
1550
1505
  /**
1551
1506
  * @license
1552
1507
  * @monterosa/sdk-interact-kit
@@ -1868,5 +1823,155 @@ function onElementRevoked(event, callback) {
1868
1823
  return subscribe$2(event, 'revoke', callback);
1869
1824
  }
1870
1825
 
1871
- export { Answer, AnswerError, Channel, ConnectionHealthState, ElementImpl, ElementState, ElementType, EventImpl, EventState, Klass, ProjectImpl, State, answer, fetchListings, getConnect, getConnectionHealth, getElement, getElementMemoized, getElements, getElementsMemoized, getEvent, getEventMemoized, getEvents, getEventsMemoized, getProject, getProjectMemoized, login, onConnectionHealthState, onElementPublished, onElementResults, onElementRevoked, onElementStateChanged, onElementUpdated, onEventAdded, onEventPublished, onEventRemoved, onEventState, onEventUpdated, onProjectFieldsUpdated, onProjectListingsUpdated, validateAnswer };
1826
+ /**
1827
+ * @license
1828
+ * @monterosa/sdk-interact-kit
1829
+ *
1830
+ * Copyright © 2025 Monterosa Productions Limited. All rights reserved.
1831
+ *
1832
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
1833
+ */
1834
+ var PresenceCounterState;
1835
+ (function (PresenceCounterState) {
1836
+ PresenceCounterState["Opened"] = "opened";
1837
+ PresenceCounterState["Closed"] = "closed";
1838
+ })(PresenceCounterState || (PresenceCounterState = {}));
1839
+
1840
+ /**
1841
+ * @license
1842
+ * @monterosa/sdk-interact-kit
1843
+ *
1844
+ * Copyright © 2023 Monterosa Productions Limited. All rights reserved.
1845
+ *
1846
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
1847
+ */
1848
+ const logger = new Logger('@monterosa/sdk-interact-kit');
1849
+
1850
+ /**
1851
+ * @license
1852
+ * @monterosa/sdk-interact-kit
1853
+ *
1854
+ * Copyright © 2025 Monterosa Productions Limited. All rights reserved.
1855
+ *
1856
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
1857
+ */
1858
+ class PresenceCounterImpl extends Emitter {
1859
+ constructor(host, id) {
1860
+ super();
1861
+ this.host = host;
1862
+ this.id = id;
1863
+ this.state = PresenceCounterState.Closed;
1864
+ this.lastCount = 0;
1865
+ this.connect = null;
1866
+ this.boundHandleMessage = this.handleMessage.bind(this);
1867
+ this.boundHandleTimeout = this.handleTimeout.bind(this);
1868
+ }
1869
+ async init() {
1870
+ this.connect = await getConnect(this.host);
1871
+ this.connect.on('message', this.boundHandleMessage);
1872
+ }
1873
+ get isOpened() {
1874
+ return this.state === PresenceCounterState.Opened;
1875
+ }
1876
+ async handleMessage(message) {
1877
+ const { id, klass, data } = message;
1878
+ if (id !== this.id || klass !== Klass.SubsCounter) {
1879
+ return;
1880
+ }
1881
+ try {
1882
+ const subsData = JSON.parse(data[0]);
1883
+ this.handleCounterUpdate(subsData.counter);
1884
+ this.resetTimeout(subsData.next_update_at);
1885
+ }
1886
+ catch (e) {
1887
+ logger.warn("Couldn't parse subscounter message.");
1888
+ }
1889
+ }
1890
+ handleCounterUpdate(count) {
1891
+ if (count < 0) {
1892
+ return;
1893
+ }
1894
+ let shouldEmitUpdated = false;
1895
+ let shouldEmitState = false;
1896
+ if (this.lastCount !== count) {
1897
+ shouldEmitUpdated = true;
1898
+ this.lastCount = count;
1899
+ }
1900
+ if (this.state === PresenceCounterState.Closed) {
1901
+ shouldEmitState = true;
1902
+ this.state = PresenceCounterState.Opened;
1903
+ }
1904
+ if (shouldEmitUpdated) {
1905
+ this.emit('updated', this.lastCount);
1906
+ }
1907
+ if (shouldEmitState) {
1908
+ this.emit('state', PresenceCounterState.Opened);
1909
+ }
1910
+ }
1911
+ handleTimeout() {
1912
+ this.state = PresenceCounterState.Closed;
1913
+ this.emit('state', PresenceCounterState.Closed);
1914
+ }
1915
+ resetTimeout(nextUpdateAt) {
1916
+ clearTimeout(this.closeTimeout);
1917
+ this.closeTimeout = setTimeout(this.boundHandleTimeout,
1918
+ // because of the time difference between the server and the client,
1919
+ // we need to add 3 seconds to the timeout
1920
+ (nextUpdateAt - now() + 3) * 1000);
1921
+ }
1922
+ destroy() {
1923
+ if (this.connect !== null) {
1924
+ this.connect.off('message', this.boundHandleMessage);
1925
+ }
1926
+ }
1927
+ }
1928
+
1929
+ /**
1930
+ * @license
1931
+ * @monterosa/sdk-interact-kit
1932
+ *
1933
+ * Copyright © 2025 Monterosa Productions Limited. All rights reserved.
1934
+ *
1935
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
1936
+ */
1937
+ const presenceCounters = new Map();
1938
+ const getPresenceCounterMemoized = memoizePromise(async (host, id) => {
1939
+ if (presenceCounters.has(id)) {
1940
+ return presenceCounters.get(id);
1941
+ }
1942
+ const presenceCounter = new PresenceCounterImpl(host, id);
1943
+ await presenceCounter.init();
1944
+ presenceCounters.set(id, presenceCounter);
1945
+ return presenceCounter;
1946
+ }, (_, id) => id);
1947
+ async function getPresenceCounter(project) {
1948
+ if (project === undefined) {
1949
+ project = await getProject();
1950
+ }
1951
+ return getPresenceCounterMemoized(project.context.sdk.options.host, project.id);
1952
+ }
1953
+ function onPresenceCounterUpdate(presenceCounter, callback) {
1954
+ presenceCounter.on('updated', callback);
1955
+ return () => presenceCounter.off('updated', callback);
1956
+ }
1957
+ function onPresenceCounterOpen(presenceCounter, callback) {
1958
+ const handler = (state) => {
1959
+ if (state === PresenceCounterState.Opened) {
1960
+ callback();
1961
+ }
1962
+ };
1963
+ presenceCounter.on('state', handler);
1964
+ return () => presenceCounter.off('state', handler);
1965
+ }
1966
+ function onPresenceCounterClose(presenceCounter, callback) {
1967
+ const handler = (state) => {
1968
+ if (state === PresenceCounterState.Closed) {
1969
+ callback();
1970
+ }
1971
+ };
1972
+ presenceCounter.on('state', handler);
1973
+ return () => presenceCounter.off('state', handler);
1974
+ }
1975
+
1976
+ export { Answer, AnswerError, Channel, ConnectionHealthState, ElementImpl, ElementState, ElementType, EventImpl, EventState, Klass, PresenceCounterState, ProjectImpl, State, answer, fetchListings, getConnect, getConnectionHealth, getElement, getElementMemoized, getElements, getElementsMemoized, getEvent, getEventMemoized, getEvents, getEventsMemoized, getPresenceCounter, getProject, getProjectMemoized, login, onConnectionHealthState, onElementPublished, onElementResults, onElementRevoked, onElementStateChanged, onElementUpdated, onEventAdded, onEventPublished, onEventRemoved, onEventState, onEventUpdated, onPresenceCounterClose, onPresenceCounterOpen, onPresenceCounterUpdate, onProjectFieldsUpdated, onProjectListingsUpdated, validateAnswer };
1872
1977
  //# sourceMappingURL=index.esm.js.map