summaryrefslogtreecommitdiff
path: root/includes/external/matrix/node_modules/matrix-js-sdk/lib/models/beacon.js
diff options
context:
space:
mode:
authorRaindropsSys <contact@minteck.org>2023-04-24 14:03:36 +0200
committerRaindropsSys <contact@minteck.org>2023-04-24 14:03:36 +0200
commit633c92eae865e957121e08de634aeee11a8b3992 (patch)
tree09d881bee1dae0b6eee49db1dfaf0f500240606c /includes/external/matrix/node_modules/matrix-js-sdk/lib/models/beacon.js
parentc4657e4509733699c0f26a3c900bab47e915d5a0 (diff)
downloadpluralconnect-633c92eae865e957121e08de634aeee11a8b3992.tar.gz
pluralconnect-633c92eae865e957121e08de634aeee11a8b3992.tar.bz2
pluralconnect-633c92eae865e957121e08de634aeee11a8b3992.zip
Updated 18 files, added 1692 files and deleted includes/system/compare.inc (automated)
Diffstat (limited to 'includes/external/matrix/node_modules/matrix-js-sdk/lib/models/beacon.js')
-rw-r--r--includes/external/matrix/node_modules/matrix-js-sdk/lib/models/beacon.js184
1 files changed, 184 insertions, 0 deletions
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/models/beacon.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/models/beacon.js
new file mode 100644
index 0000000..93a226d
--- /dev/null
+++ b/includes/external/matrix/node_modules/matrix-js-sdk/lib/models/beacon.js
@@ -0,0 +1,184 @@
+"use strict";
+
+var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.isTimestampInDuration = exports.getBeaconInfoIdentifier = exports.BeaconEvent = exports.Beacon = void 0;
+var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
+var _contentHelpers = require("../content-helpers");
+var _utils = require("../utils");
+var _typedEventEmitter = require("./typed-event-emitter");
+/*
+Copyright 2022 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+let BeaconEvent;
+exports.BeaconEvent = BeaconEvent;
+(function (BeaconEvent) {
+ BeaconEvent["New"] = "Beacon.new";
+ BeaconEvent["Update"] = "Beacon.update";
+ BeaconEvent["LivenessChange"] = "Beacon.LivenessChange";
+ BeaconEvent["Destroy"] = "Beacon.Destroy";
+ BeaconEvent["LocationUpdate"] = "Beacon.LocationUpdate";
+})(BeaconEvent || (exports.BeaconEvent = BeaconEvent = {}));
+const isTimestampInDuration = (startTimestamp, durationMs, timestamp) => timestamp >= startTimestamp && startTimestamp + durationMs >= timestamp;
+
+// beacon info events are uniquely identified by
+// `<roomId>_<state_key>`
+exports.isTimestampInDuration = isTimestampInDuration;
+const getBeaconInfoIdentifier = event => `${event.getRoomId()}_${event.getStateKey()}`;
+
+// https://github.com/matrix-org/matrix-spec-proposals/pull/3672
+exports.getBeaconInfoIdentifier = getBeaconInfoIdentifier;
+class Beacon extends _typedEventEmitter.TypedEventEmitter {
+ // beaconInfo is assigned by setBeaconInfo in the constructor
+ // ! to make tsc believe it is definitely assigned
+
+ constructor(rootEvent) {
+ super();
+ this.rootEvent = rootEvent;
+ (0, _defineProperty2.default)(this, "roomId", void 0);
+ (0, _defineProperty2.default)(this, "_beaconInfo", void 0);
+ (0, _defineProperty2.default)(this, "_isLive", void 0);
+ (0, _defineProperty2.default)(this, "livenessWatchTimeout", void 0);
+ (0, _defineProperty2.default)(this, "_latestLocationEvent", void 0);
+ (0, _defineProperty2.default)(this, "clearLatestLocation", () => {
+ this._latestLocationEvent = undefined;
+ this.emit(BeaconEvent.LocationUpdate, this.latestLocationState);
+ });
+ this.roomId = this.rootEvent.getRoomId();
+ this.setBeaconInfo(this.rootEvent);
+ }
+ get isLive() {
+ return !!this._isLive;
+ }
+ get identifier() {
+ return getBeaconInfoIdentifier(this.rootEvent);
+ }
+ get beaconInfoId() {
+ return this.rootEvent.getId();
+ }
+ get beaconInfoOwner() {
+ return this.rootEvent.getStateKey();
+ }
+ get beaconInfoEventType() {
+ return this.rootEvent.getType();
+ }
+ get beaconInfo() {
+ return this._beaconInfo;
+ }
+ get latestLocationState() {
+ return this._latestLocationEvent && (0, _contentHelpers.parseBeaconContent)(this._latestLocationEvent.getContent());
+ }
+ get latestLocationEvent() {
+ return this._latestLocationEvent;
+ }
+ update(beaconInfoEvent) {
+ if (getBeaconInfoIdentifier(beaconInfoEvent) !== this.identifier) {
+ throw new Error("Invalid updating event");
+ }
+ // don't update beacon with an older event
+ if (beaconInfoEvent.getTs() < this.rootEvent.getTs()) {
+ return;
+ }
+ this.rootEvent = beaconInfoEvent;
+ this.setBeaconInfo(this.rootEvent);
+ this.emit(BeaconEvent.Update, beaconInfoEvent, this);
+ this.clearLatestLocation();
+ }
+ destroy() {
+ if (this.livenessWatchTimeout) {
+ clearTimeout(this.livenessWatchTimeout);
+ }
+ this._isLive = false;
+ this.emit(BeaconEvent.Destroy, this.identifier);
+ }
+
+ /**
+ * Monitor liveness of a beacon
+ * Emits BeaconEvent.LivenessChange when beacon expires
+ */
+ monitorLiveness() {
+ if (this.livenessWatchTimeout) {
+ clearTimeout(this.livenessWatchTimeout);
+ }
+ this.checkLiveness();
+ if (!this.beaconInfo) return;
+ if (this.isLive) {
+ const expiryInMs = this.beaconInfo.timestamp + this.beaconInfo.timeout - Date.now();
+ if (expiryInMs > 1) {
+ this.livenessWatchTimeout = setTimeout(() => {
+ this.monitorLiveness();
+ }, expiryInMs);
+ }
+ } else if (this.beaconInfo.timestamp > Date.now()) {
+ // beacon start timestamp is in the future
+ // check liveness again then
+ this.livenessWatchTimeout = setTimeout(() => {
+ this.monitorLiveness();
+ }, this.beaconInfo.timestamp - Date.now());
+ }
+ }
+
+ /**
+ * Process Beacon locations
+ * Emits BeaconEvent.LocationUpdate
+ */
+ addLocations(beaconLocationEvents) {
+ var _validLocationEvents$;
+ // discard locations for beacons that are not live
+ if (!this.isLive) {
+ return;
+ }
+ const validLocationEvents = beaconLocationEvents.filter(event => {
+ const content = event.getContent();
+ const parsed = (0, _contentHelpers.parseBeaconContent)(content);
+ if (!parsed.uri || !parsed.timestamp) return false; // we won't be able to process these
+ const {
+ timestamp
+ } = parsed;
+ return this._beaconInfo.timestamp &&
+ // only include positions that were taken inside the beacon's live period
+ isTimestampInDuration(this._beaconInfo.timestamp, this._beaconInfo.timeout, timestamp) && (
+ // ignore positions older than our current latest location
+ !this.latestLocationState || timestamp > this.latestLocationState.timestamp);
+ });
+ const latestLocationEvent = (_validLocationEvents$ = validLocationEvents.sort(_utils.sortEventsByLatestContentTimestamp)) === null || _validLocationEvents$ === void 0 ? void 0 : _validLocationEvents$[0];
+ if (latestLocationEvent) {
+ this._latestLocationEvent = latestLocationEvent;
+ this.emit(BeaconEvent.LocationUpdate, this.latestLocationState);
+ }
+ }
+ setBeaconInfo(event) {
+ this._beaconInfo = (0, _contentHelpers.parseBeaconInfoContent)(event.getContent());
+ this.checkLiveness();
+ }
+ checkLiveness() {
+ const prevLiveness = this.isLive;
+
+ // element web sets a beacon's start timestamp to the senders local current time
+ // when Alice's system clock deviates slightly from Bob's a beacon Alice intended to be live
+ // may have a start timestamp in the future from Bob's POV
+ // handle this by adding 6min of leniency to the start timestamp when it is in the future
+ if (!this.beaconInfo) return;
+ const startTimestamp = this.beaconInfo.timestamp > Date.now() ? this.beaconInfo.timestamp - 360000 /* 6min */ : this.beaconInfo.timestamp;
+ this._isLive = !!this._beaconInfo.live && !!startTimestamp && isTimestampInDuration(startTimestamp, this._beaconInfo.timeout, Date.now());
+ if (prevLiveness !== this.isLive) {
+ this.emit(BeaconEvent.LivenessChange, this.isLive, this);
+ }
+ }
+}
+exports.Beacon = Beacon;
+//# sourceMappingURL=beacon.js.map \ No newline at end of file