@monterosa/sdk-interact-kit 0.19.0-rc.5 → 2.0.0-rc.1
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/core/element/factory.d.ts +3 -3
- package/dist/core/event/event_impl.d.ts +4 -1
- package/dist/core/project/api.d.ts +5 -6
- package/dist/core/project/project_impl.d.ts +5 -0
- package/dist/index.cjs.js +170 -111
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +87 -61
- package/dist/index.esm.js.map +1 -1
- package/package.json +10 -6
- package/dist/core/project/internal.d.ts +0 -10
package/dist/index.esm.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
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, checksum, onTick, now,
|
|
2
|
+
import { Emitter, memoizePromise, subscribe as subscribe$2, checksum, onTick, now, calculatePercentage, getErrorMessage, createError } from '@monterosa/sdk-util';
|
|
3
3
|
import { getSdk, Logger } from '@monterosa/sdk-core';
|
|
4
|
+
import { fetchSettings } from '@monterosa/sdk-interact-interop';
|
|
5
|
+
import { storageRead, storageWrite } from '@monterosa/sdk-storage-kit';
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* @license
|
|
@@ -286,20 +288,6 @@ function onConnectionHealthState(connectionHealth, callback) {
|
|
|
286
288
|
return subscribe$2(connectionHealth, 'state', callback);
|
|
287
289
|
}
|
|
288
290
|
|
|
289
|
-
/**
|
|
290
|
-
* @license
|
|
291
|
-
* @monterosa/sdk-interact-kit
|
|
292
|
-
*
|
|
293
|
-
* Copyright © 2022 Monterosa Productions Limited. All rights reserved.
|
|
294
|
-
*
|
|
295
|
-
* More details on the license can be found at https://www.monterosa.co/sdk/license
|
|
296
|
-
*/
|
|
297
|
-
async function fetchSettings(host, id) {
|
|
298
|
-
const response = await fetch(`https://${host}/projects/${id.substring(0, 2)}/${id}/settings.json`);
|
|
299
|
-
const data = await response.json();
|
|
300
|
-
return data;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
291
|
/**
|
|
304
292
|
* @license
|
|
305
293
|
* @monterosa/sdk-interact-kit
|
|
@@ -413,11 +401,12 @@ class ProjectImpl extends Emitter {
|
|
|
413
401
|
}
|
|
414
402
|
set listings(newListings) {
|
|
415
403
|
const createdEvents = this._calculateCreatedEvents(newListings);
|
|
404
|
+
const updatedEvents = this._calculateUpdatedEvents(newListings);
|
|
416
405
|
const deletedEvents = this._calculateDeletedEvents(newListings);
|
|
417
406
|
this._listings = Object.assign({}, newListings);
|
|
418
407
|
this._updateLocales(newListings);
|
|
419
408
|
this._updateEventsChecksum(newListings);
|
|
420
|
-
this._emitListingsEvents(createdEvents, deletedEvents);
|
|
409
|
+
this._emitListingsEvents(createdEvents, updatedEvents, deletedEvents);
|
|
421
410
|
}
|
|
422
411
|
/**
|
|
423
412
|
* Calculates events that were created (present in new listings but not in old)
|
|
@@ -428,6 +417,21 @@ class ProjectImpl extends Emitter {
|
|
|
428
417
|
}
|
|
429
418
|
return newListings.events.filter(({ id }) => !this._listings.events.some((event) => id === event.id));
|
|
430
419
|
}
|
|
420
|
+
/**
|
|
421
|
+
* Calculates events that were updated (present in old listings and new,
|
|
422
|
+
* but with different digest)
|
|
423
|
+
*/
|
|
424
|
+
_calculateUpdatedEvents(newListings) {
|
|
425
|
+
if (!this._listings) {
|
|
426
|
+
return [];
|
|
427
|
+
}
|
|
428
|
+
return newListings.events.filter((event) => {
|
|
429
|
+
// find event data in new listings
|
|
430
|
+
const existingEvent = this._listings.events.find(({ id }) => event.id === id);
|
|
431
|
+
// return true if event data is found and digest is different
|
|
432
|
+
return existingEvent && event.digest !== existingEvent.digest;
|
|
433
|
+
});
|
|
434
|
+
}
|
|
431
435
|
/**
|
|
432
436
|
* Calculates events that were deleted (present in old listings but not in new)
|
|
433
437
|
*/
|
|
@@ -459,16 +463,20 @@ class ProjectImpl extends Emitter {
|
|
|
459
463
|
/**
|
|
460
464
|
* Emits events based on created and deleted events
|
|
461
465
|
*/
|
|
462
|
-
_emitListingsEvents(createdEvents, deletedEvents) {
|
|
466
|
+
_emitListingsEvents(createdEvents, updatedEvents, deletedEvents) {
|
|
463
467
|
const hasCreatedEvents = createdEvents.length > 0;
|
|
464
468
|
const hasDeletedEvents = deletedEvents.length > 0;
|
|
465
|
-
const
|
|
469
|
+
const hasUpdatedEvents = updatedEvents.length > 0;
|
|
470
|
+
const hasChanges = hasCreatedEvents || hasDeletedEvents || hasUpdatedEvents;
|
|
466
471
|
if (hasCreatedEvents) {
|
|
467
472
|
this.emit('listings_events_created', createdEvents);
|
|
468
473
|
}
|
|
469
474
|
if (hasDeletedEvents) {
|
|
470
475
|
this.emit('listings_events_deleted', deletedEvents);
|
|
471
476
|
}
|
|
477
|
+
if (hasUpdatedEvents) {
|
|
478
|
+
this.emit('listings_events_updated', updatedEvents);
|
|
479
|
+
}
|
|
472
480
|
if (hasChanges) {
|
|
473
481
|
this.emit('listings');
|
|
474
482
|
}
|
|
@@ -650,14 +658,6 @@ const getProjectMemoized = memoizePromise(async (sdk) => {
|
|
|
650
658
|
function getProject(sdk = getSdk()) {
|
|
651
659
|
return getProjectMemoized(sdk);
|
|
652
660
|
}
|
|
653
|
-
/**
|
|
654
|
-
* @internal
|
|
655
|
-
*/
|
|
656
|
-
async function fetchListings(host, projectId) {
|
|
657
|
-
const response = await fetch(`https://${host}/projects/${projectId.substring(0, 2)}/${projectId}/listings.json`);
|
|
658
|
-
const data = (await response.json());
|
|
659
|
-
return data;
|
|
660
|
-
}
|
|
661
661
|
/**
|
|
662
662
|
* Adds an observer for when {@link InteractProject.fields | project fields}
|
|
663
663
|
* are updated
|
|
@@ -666,9 +666,13 @@ function onProjectFieldsUpdated(project, callback) {
|
|
|
666
666
|
return subscribe$2(project, 'updated', callback);
|
|
667
667
|
}
|
|
668
668
|
/**
|
|
669
|
-
*
|
|
669
|
+
* Adds an observer that is called when the project listings are updated.
|
|
670
|
+
*
|
|
671
|
+
* @deprecated Use {@link onEventAdded()}, {@link onEventUpdated()} and
|
|
672
|
+
* {@link onEventRemoved()} instead
|
|
670
673
|
*/
|
|
671
674
|
function onProjectListingsUpdated(project, callback) {
|
|
675
|
+
console.warn('onProjectListingsUpdated() is deprecated. Please use onEventAdded(), onEventUpdated() and onEventRemoved() instead');
|
|
672
676
|
return subscribe$2(project, 'listings', callback);
|
|
673
677
|
}
|
|
674
678
|
|
|
@@ -790,11 +794,12 @@ class EventImpl extends Emitter {
|
|
|
790
794
|
this._context = context;
|
|
791
795
|
this._state = this.calculateState();
|
|
792
796
|
this._internalState = this.calculateInternalState();
|
|
793
|
-
this.
|
|
794
|
-
this.
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
this.
|
|
797
|
+
this.boundHandleState = this.handleState.bind(this);
|
|
798
|
+
this.boundHandleInternalState = this.handleInternalState.bind(this);
|
|
799
|
+
this.boundHandleEventsUpdated = this.handleEventsUpdated.bind(this);
|
|
800
|
+
this.unsubscribeStateHandler = onTick(this.boundHandleState);
|
|
801
|
+
this.unsubscribeInternalStateHandler = onTick(this.boundHandleInternalState);
|
|
802
|
+
this.unsubscribeListingsHandler = subscribe$2(this.context.project, 'listings_events_updated', this.boundHandleEventsUpdated);
|
|
798
803
|
}
|
|
799
804
|
calculateState() {
|
|
800
805
|
if (!this._data.started || now() < this.startAt) {
|
|
@@ -837,11 +842,13 @@ class EventImpl extends Emitter {
|
|
|
837
842
|
this.emit('internal_state', internalState);
|
|
838
843
|
}
|
|
839
844
|
}
|
|
840
|
-
|
|
841
|
-
const {
|
|
842
|
-
const data = project.events.find(({ id }) => id === this.id);
|
|
845
|
+
handleEventsUpdated(events) {
|
|
846
|
+
const data = events.find(({ id }) => id === this.id);
|
|
843
847
|
if (data && this._data.digest !== data.digest) {
|
|
844
848
|
this._data = data;
|
|
849
|
+
// Forcing state recalculation to ensure the event is in the correct state
|
|
850
|
+
this.handleState();
|
|
851
|
+
this.handleInternalState();
|
|
845
852
|
this.emit('updated');
|
|
846
853
|
}
|
|
847
854
|
}
|
|
@@ -1431,6 +1438,7 @@ class ElementImpl extends Emitter {
|
|
|
1431
1438
|
}
|
|
1432
1439
|
update(data) {
|
|
1433
1440
|
this._data = data;
|
|
1441
|
+
this.handleState();
|
|
1434
1442
|
}
|
|
1435
1443
|
destroy() {
|
|
1436
1444
|
this.unsubscribeStateHandler();
|
|
@@ -1569,13 +1577,12 @@ class ElementImpl extends Emitter {
|
|
|
1569
1577
|
* More details on the license can be found at https://www.monterosa.co/sdk/license
|
|
1570
1578
|
*/
|
|
1571
1579
|
const elements = new Map();
|
|
1572
|
-
|
|
1573
|
-
function buildElement(options, context) {
|
|
1580
|
+
async function buildElement(options, context) {
|
|
1574
1581
|
if (elements.has(options.id)) {
|
|
1575
1582
|
return elements.get(options.id);
|
|
1576
1583
|
}
|
|
1577
1584
|
const element = new ElementImpl(options, context);
|
|
1578
|
-
restoreAnswer(element);
|
|
1585
|
+
await restoreAnswer(element);
|
|
1579
1586
|
elements.set(element.id, element);
|
|
1580
1587
|
return element;
|
|
1581
1588
|
}
|
|
@@ -1626,14 +1633,21 @@ async function handleCreateMessage(message) {
|
|
|
1626
1633
|
}
|
|
1627
1634
|
if (elements.has(options.id)) {
|
|
1628
1635
|
const element = elements.get(options.id);
|
|
1629
|
-
if (options.updated_at > element.updatedAt
|
|
1636
|
+
if (options.updated_at > element.updatedAt ||
|
|
1637
|
+
// This is a workaround to handle a Studio issue when two /create/ messages
|
|
1638
|
+
// are sent upon correct option reveal. The first /create/ message contains
|
|
1639
|
+
// the same duration but a different updated_at timestamp. The second /create/
|
|
1640
|
+
// message contains the same updated_at timestamp but a different duration.
|
|
1641
|
+
// Therefore, we need to check if the duration is different to ensure that
|
|
1642
|
+
// the element is updated correctly.
|
|
1643
|
+
options.duration !== element.duration) {
|
|
1630
1644
|
element.update(options);
|
|
1631
1645
|
event.emit('update', element);
|
|
1632
1646
|
}
|
|
1633
1647
|
}
|
|
1634
1648
|
else {
|
|
1635
1649
|
const context = Object.assign(Object.assign({}, event.context), { event });
|
|
1636
|
-
const element = buildElement(options, context);
|
|
1650
|
+
const element = await buildElement(options, context);
|
|
1637
1651
|
event.emit('publish', element);
|
|
1638
1652
|
}
|
|
1639
1653
|
}
|
|
@@ -1678,10 +1692,13 @@ function handleRevealMessage(message) {
|
|
|
1678
1692
|
if (!element) {
|
|
1679
1693
|
return;
|
|
1680
1694
|
}
|
|
1681
|
-
element.correctOption
|
|
1682
|
-
|
|
1695
|
+
if (element.correctOption !== correctOption) {
|
|
1696
|
+
element.correctOption = correctOption;
|
|
1697
|
+
element.context.event.emit('update', element);
|
|
1698
|
+
}
|
|
1683
1699
|
}
|
|
1684
1700
|
async function handleEventHistory(history) {
|
|
1701
|
+
var _a, e_1, _b, _c;
|
|
1685
1702
|
if (history.timeline.length === 0) {
|
|
1686
1703
|
return;
|
|
1687
1704
|
}
|
|
@@ -1690,11 +1707,28 @@ async function handleEventHistory(history) {
|
|
|
1690
1707
|
return;
|
|
1691
1708
|
}
|
|
1692
1709
|
const context = Object.assign(Object.assign({}, event.context), { event });
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1710
|
+
try {
|
|
1711
|
+
for (var _d = true, _e = __asyncValues(history.timeline), _f; _f = await _e.next(), _a = _f.done, !_a;) {
|
|
1712
|
+
_c = _f.value;
|
|
1713
|
+
_d = false;
|
|
1714
|
+
try {
|
|
1715
|
+
const snapshot = _c;
|
|
1716
|
+
if (!elements.has(snapshot.id)) {
|
|
1717
|
+
await buildElement(snapshot, context);
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
finally {
|
|
1721
|
+
_d = true;
|
|
1722
|
+
}
|
|
1696
1723
|
}
|
|
1697
1724
|
}
|
|
1725
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
1726
|
+
finally {
|
|
1727
|
+
try {
|
|
1728
|
+
if (!_d && !_a && (_b = _e.return)) await _b.call(_e);
|
|
1729
|
+
}
|
|
1730
|
+
finally { if (e_1) throw e_1.error; }
|
|
1731
|
+
}
|
|
1698
1732
|
}
|
|
1699
1733
|
async function sendAnswer(element, userAnswer) {
|
|
1700
1734
|
const { project, event } = element.context;
|
|
@@ -1705,27 +1739,19 @@ async function sendAnswer(element, userAnswer) {
|
|
|
1705
1739
|
.join(':');
|
|
1706
1740
|
connect.sendVote(event.id, element.pollId, answer);
|
|
1707
1741
|
}
|
|
1708
|
-
function storeAnswer(element, userAnswer) {
|
|
1742
|
+
async function storeAnswer(element, userAnswer) {
|
|
1709
1743
|
try {
|
|
1710
1744
|
element.userAnswer = userAnswer;
|
|
1711
|
-
|
|
1712
|
-
// Can throw a "QuotaExceededError" DOMException exception
|
|
1713
|
-
// if the quota has been exceeded.
|
|
1714
|
-
setItem(`element_${element.id}_vote`, JSON.stringify(userAnswer));
|
|
1715
|
-
}
|
|
1745
|
+
await storageWrite(`element_${element.id}_vote`, JSON.stringify(userAnswer));
|
|
1716
1746
|
}
|
|
1717
1747
|
catch (err) {
|
|
1718
|
-
|
|
1719
|
-
console.warn(`Can't store user answer: ${err.message}`);
|
|
1720
|
-
}
|
|
1748
|
+
console.warn(`Failed to store user answer: ${getErrorMessage(err)}`);
|
|
1721
1749
|
}
|
|
1722
1750
|
}
|
|
1723
|
-
function restoreAnswer(element) {
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
element.userAnswer = Answer.fromJSON(userAnswer);
|
|
1728
|
-
}
|
|
1751
|
+
async function restoreAnswer(element) {
|
|
1752
|
+
const userAnswer = await storageRead(`element_${element.id}_vote`);
|
|
1753
|
+
if (userAnswer !== null) {
|
|
1754
|
+
element.userAnswer = Answer.fromJSON(userAnswer);
|
|
1729
1755
|
}
|
|
1730
1756
|
}
|
|
1731
1757
|
|
|
@@ -2031,5 +2057,5 @@ function onPresenceCounterClose(presenceCounter, callback) {
|
|
|
2031
2057
|
return () => presenceCounter.off('state', handler);
|
|
2032
2058
|
}
|
|
2033
2059
|
|
|
2034
|
-
export { Answer, AnswerError, Channel, ConnectionHealthState, ElementImpl, ElementState, ElementType, EventImpl, EventState, Klass, PresenceCounterState, ProjectImpl, State, answer,
|
|
2060
|
+
export { Answer, AnswerError, Channel, ConnectionHealthState, ElementImpl, ElementState, ElementType, EventImpl, EventState, Klass, PresenceCounterState, ProjectImpl, State, answer, 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 };
|
|
2035
2061
|
//# sourceMappingURL=index.esm.js.map
|