matrix-js-sdk 41.5.0 → 41.6.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/CHANGELOG.md +7 -0
- package/lib/ReEmitter.js +1 -1
- package/lib/ReEmitter.js.map +1 -1
- package/lib/ToDeviceMessageQueue.js +2 -2
- package/lib/ToDeviceMessageQueue.js.map +1 -1
- package/lib/autodiscovery.js +0 -1
- package/lib/autodiscovery.js.map +1 -1
- package/lib/client.js +112 -165
- package/lib/client.js.map +1 -1
- package/lib/common-crypto/CryptoBackend.js +0 -2
- package/lib/common-crypto/CryptoBackend.js.map +1 -1
- package/lib/content-helpers.js +3 -5
- package/lib/content-helpers.js.map +1 -1
- package/lib/content-repo.js +7 -1
- package/lib/content-repo.js.map +1 -1
- package/lib/crypto/store/indexeddb-crypto-store-backend.js +9 -11
- package/lib/crypto/store/indexeddb-crypto-store-backend.js.map +1 -1
- package/lib/crypto/store/indexeddb-crypto-store.js +0 -2
- package/lib/crypto/store/indexeddb-crypto-store.js.map +1 -1
- package/lib/crypto/store/localStorage-crypto-store.js +11 -9
- package/lib/crypto/store/localStorage-crypto-store.js.map +1 -1
- package/lib/crypto/store/memory-crypto-store.js +11 -9
- package/lib/crypto/store/memory-crypto-store.js.map +1 -1
- package/lib/crypto-api/index.js +58 -58
- package/lib/crypto-api/index.js.map +1 -1
- package/lib/embedded.js +29 -45
- package/lib/embedded.js.map +1 -1
- package/lib/extensible_events_v1/MessageEvent.js +15 -15
- package/lib/extensible_events_v1/MessageEvent.js.map +1 -1
- package/lib/extensible_events_v1/PollEndEvent.js +8 -8
- package/lib/extensible_events_v1/PollEndEvent.js.map +1 -1
- package/lib/extensible_events_v1/PollResponseEvent.js +0 -1
- package/lib/extensible_events_v1/PollResponseEvent.js.map +1 -1
- package/lib/extensible_events_v1/PollStartEvent.js +28 -28
- package/lib/extensible_events_v1/PollStartEvent.js.map +1 -1
- package/lib/feature.js +5 -1
- package/lib/feature.js.map +1 -1
- package/lib/filter-component.js +4 -1
- package/lib/filter-component.js.map +1 -1
- package/lib/filter.js +1 -3
- package/lib/filter.js.map +1 -1
- package/lib/http-api/errors.js +20 -16
- package/lib/http-api/errors.js.map +1 -1
- package/lib/http-api/fetch.js +4 -6
- package/lib/http-api/fetch.js.map +1 -1
- package/lib/http-api/refresh.js +10 -12
- package/lib/http-api/refresh.js.map +1 -1
- package/lib/interactive-auth.js +1 -11
- package/lib/interactive-auth.js.map +1 -1
- package/lib/logger.js +0 -2
- package/lib/logger.js.map +1 -1
- package/lib/matrixrtc/CallMembership.js +43 -57
- package/lib/matrixrtc/CallMembership.js.map +1 -1
- package/lib/matrixrtc/MatrixRTCSession.js +19 -24
- package/lib/matrixrtc/MatrixRTCSession.js.map +1 -1
- package/lib/matrixrtc/MatrixRTCSessionManager.js +2 -3
- package/lib/matrixrtc/MatrixRTCSessionManager.js.map +1 -1
- package/lib/matrixrtc/MembershipManager.js +23 -30
- package/lib/matrixrtc/MembershipManager.js.map +1 -1
- package/lib/matrixrtc/MembershipManagerActionScheduler.js +1 -2
- package/lib/matrixrtc/MembershipManagerActionScheduler.js.map +1 -1
- package/lib/matrixrtc/RTCEncryptionManager.js +8 -11
- package/lib/matrixrtc/RTCEncryptionManager.js.map +1 -1
- package/lib/matrixrtc/ToDeviceKeyTransport.js +4 -4
- package/lib/matrixrtc/ToDeviceKeyTransport.js.map +1 -1
- package/lib/matrixrtc/utils.js +7 -1
- package/lib/matrixrtc/utils.js.map +1 -1
- package/lib/models/MSC3089TreeSpace.js +5 -7
- package/lib/models/MSC3089TreeSpace.js.map +1 -1
- package/lib/models/beacon.js +5 -11
- package/lib/models/beacon.js.map +1 -1
- package/lib/models/device.js +0 -7
- package/lib/models/device.js.map +1 -1
- package/lib/models/event-context.js +1 -2
- package/lib/models/event-context.js.map +1 -1
- package/lib/models/event-timeline-set.js +16 -26
- package/lib/models/event-timeline-set.js.map +1 -1
- package/lib/models/event-timeline.js +8 -15
- package/lib/models/event-timeline.js.map +1 -1
- package/lib/models/event.js +20 -37
- package/lib/models/event.js.map +1 -1
- package/lib/models/invites-ignorer.js +8 -12
- package/lib/models/invites-ignorer.js.map +1 -1
- package/lib/models/poll.js +7 -13
- package/lib/models/poll.js.map +1 -1
- package/lib/models/read-receipt.js +8 -4
- package/lib/models/read-receipt.js.map +1 -1
- package/lib/models/related-relations.js +0 -2
- package/lib/models/related-relations.js.map +1 -1
- package/lib/models/relations-container.js +4 -6
- package/lib/models/relations-container.js.map +1 -1
- package/lib/models/relations.js +7 -10
- package/lib/models/relations.js.map +1 -1
- package/lib/models/room-member.js +2 -24
- package/lib/models/room-member.js.map +1 -1
- package/lib/models/room-receipts.js +25 -22
- package/lib/models/room-receipts.js.map +1 -1
- package/lib/models/room-state.js +2 -2
- package/lib/models/room-state.js.map +1 -1
- package/lib/models/room-sticky-events.js +20 -5
- package/lib/models/room-sticky-events.js.map +1 -1
- package/lib/models/room.js +82 -105
- package/lib/models/room.js.map +1 -1
- package/lib/models/thread.js +12 -57
- package/lib/models/thread.js.map +1 -1
- package/lib/models/user.js +1 -20
- package/lib/models/user.js.map +1 -1
- package/lib/oidc/authorize.js +23 -32
- package/lib/oidc/authorize.js.map +1 -1
- package/lib/oidc/tokenRefresher.js +8 -11
- package/lib/oidc/tokenRefresher.js.map +1 -1
- package/lib/pushprocessor.js +8 -5
- package/lib/pushprocessor.js.map +1 -1
- package/lib/receipt-accumulator.js +12 -3
- package/lib/receipt-accumulator.js.map +1 -1
- package/lib/rendezvous/MSC4108SignInWithQR.d.ts.map +1 -1
- package/lib/rendezvous/MSC4108SignInWithQR.js +10 -23
- package/lib/rendezvous/MSC4108SignInWithQR.js.map +1 -1
- package/lib/rendezvous/channels/MSC4108SecureChannel.js +5 -10
- package/lib/rendezvous/channels/MSC4108SecureChannel.js.map +1 -1
- package/lib/rendezvous/transports/MSC4108RendezvousSession.js +5 -15
- package/lib/rendezvous/transports/MSC4108RendezvousSession.js.map +1 -1
- package/lib/room-hierarchy.js +7 -12
- package/lib/room-hierarchy.js.map +1 -1
- package/lib/rust-crypto/DehydratedDeviceManager.js +2 -3
- package/lib/rust-crypto/DehydratedDeviceManager.js.map +1 -1
- package/lib/rust-crypto/KeyClaimManager.js +1 -2
- package/lib/rust-crypto/KeyClaimManager.js.map +1 -1
- package/lib/rust-crypto/OutgoingRequestProcessor.js +11 -4
- package/lib/rust-crypto/OutgoingRequestProcessor.js.map +1 -1
- package/lib/rust-crypto/OutgoingRequestsManager.js +12 -12
- package/lib/rust-crypto/OutgoingRequestsManager.js.map +1 -1
- package/lib/rust-crypto/PerSessionKeyBackupDownloader.js +3 -5
- package/lib/rust-crypto/PerSessionKeyBackupDownloader.js.map +1 -1
- package/lib/rust-crypto/RoomEncryptor.js +6 -6
- package/lib/rust-crypto/RoomEncryptor.js.map +1 -1
- package/lib/rust-crypto/backup.js +22 -16
- package/lib/rust-crypto/backup.js.map +1 -1
- package/lib/rust-crypto/device-converter.js +13 -4
- package/lib/rust-crypto/device-converter.js.map +1 -1
- package/lib/rust-crypto/index.js +1 -3
- package/lib/rust-crypto/index.js.map +1 -1
- package/lib/rust-crypto/libolm_migration.js +13 -15
- package/lib/rust-crypto/libolm_migration.js.map +1 -1
- package/lib/rust-crypto/rust-crypto.js +52 -59
- package/lib/rust-crypto/rust-crypto.js.map +1 -1
- package/lib/rust-crypto/verification.js +10 -10
- package/lib/rust-crypto/verification.js.map +1 -1
- package/lib/scheduler.js +2 -2
- package/lib/scheduler.js.map +1 -1
- package/lib/secret-storage.js +16 -10
- package/lib/secret-storage.js.map +1 -1
- package/lib/serverCapabilities.js +2 -5
- package/lib/serverCapabilities.js.map +1 -1
- package/lib/sliding-sync-sdk.js +4 -9
- package/lib/sliding-sync-sdk.js.map +1 -1
- package/lib/sliding-sync.js +4 -9
- package/lib/sliding-sync.js.map +1 -1
- package/lib/store/indexeddb-local-backend.js +13 -8
- package/lib/store/indexeddb-local-backend.js.map +1 -1
- package/lib/store/indexeddb-remote-backend.js +6 -7
- package/lib/store/indexeddb-remote-backend.js.map +1 -1
- package/lib/store/indexeddb-store-worker.js +1 -2
- package/lib/store/indexeddb-store-worker.js.map +1 -1
- package/lib/store/indexeddb.js +4 -2
- package/lib/store/indexeddb.js.map +1 -1
- package/lib/store/memory.js +0 -4
- package/lib/store/memory.js.map +1 -1
- package/lib/sync-accumulator.js +2 -4
- package/lib/sync-accumulator.js.map +1 -1
- package/lib/sync.js +36 -43
- package/lib/sync.js.map +1 -1
- package/lib/timeline-window.js +2 -6
- package/lib/timeline-window.js.map +1 -1
- package/lib/utils/decryptAESSecretStorageItem.js +5 -1
- package/lib/utils/decryptAESSecretStorageItem.js.map +1 -1
- package/lib/utils/encryptAESSecretStorageItem.js +5 -1
- package/lib/utils/encryptAESSecretStorageItem.js.map +1 -1
- package/lib/utils.js +35 -20
- package/lib/utils.js.map +1 -1
- package/lib/webrtc/call.js +13 -45
- package/lib/webrtc/call.js.map +1 -1
- package/lib/webrtc/callEventHandler.js +0 -5
- package/lib/webrtc/callEventHandler.js.map +1 -1
- package/lib/webrtc/callFeed.js +0 -15
- package/lib/webrtc/callFeed.js.map +1 -1
- package/lib/webrtc/groupCall.js +82 -89
- package/lib/webrtc/groupCall.js.map +1 -1
- package/lib/webrtc/groupCallEventHandler.js +6 -7
- package/lib/webrtc/groupCallEventHandler.js.map +1 -1
- package/lib/webrtc/mediaHandler.js +8 -15
- package/lib/webrtc/mediaHandler.js.map +1 -1
- package/lib/webrtc/stats/callStatsReportGatherer.js +2 -5
- package/lib/webrtc/stats/callStatsReportGatherer.js.map +1 -1
- package/lib/webrtc/stats/connectionStatsReportBuilder.js +5 -1
- package/lib/webrtc/stats/connectionStatsReportBuilder.js.map +1 -1
- package/lib/webrtc/stats/groupCallStats.js +3 -4
- package/lib/webrtc/stats/groupCallStats.js.map +1 -1
- package/lib/webrtc/stats/media/mediaTrackStats.js +3 -3
- package/lib/webrtc/stats/media/mediaTrackStats.js.map +1 -1
- package/lib/webrtc/stats/media/mediaTrackStatsHandler.js +1 -1
- package/lib/webrtc/stats/media/mediaTrackStatsHandler.js.map +1 -1
- package/package.json +3 -3
- package/src/rendezvous/MSC4108SignInWithQR.ts +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"room-sticky-events.js","names":["logger","loggerInstance","TypedEventEmitter","getChild","RoomStickyEventsEvent","assertIsUserId","value","Error","startsWith","RoomStickyEventsStore","constructor","arguments","_defineProperty","Map","Set","Number","MAX_SAFE_INTEGER","now","Date","removedEvents","nextStickyEventExpiryTs","eventType","innerEvents","stickyEventsMap","entries","_this$stickyEventsMap","innerMapKey","currentEvent","previousEvents","unstableStickyExpiresAt","debug","getId","push","get","delete","set","filter","e","Math","min","size","event","unkeyedStickyEvents","length","emit","Update","scheduleStickyTimer","sortStickyEvent","eventA","eventB","_eventB$getId","_eventA$getId","getTs","stickyMapKey","stickyKey","sender","concat","getStickyEvents","innerMap","values","events","getKeyedStickyEvent","type","_this$stickyEventsMap2","getUnkeyedStickyEvent","ev","getType","getSender","addStickyEvent","_this$stickyEventsMap3","_this$stickyEventsMap4","_this$stickyEventsMap5","getContent","msc4354_sticky_key","undefined","info","added","stickyEvent","add","currentEventSet","sort","has","prevEvent","addStickyEvents","updated","result","current","previous","ex","warn","stickyEventTimer","clearTimeout","setTimeout","cleanExpiredStickyEvents","handleRedaction","redactedEvent","redactEventId","isRedacted","_innerMap$get","_this$stickyEventsMap6","mapKey","newEvents","clear"],"sources":["../../src/models/room-sticky-events.ts"],"sourcesContent":["import { logger as loggerInstance } from \"../logger.ts\";\nimport { type MatrixEvent } from \"./event.ts\";\nimport { TypedEventEmitter } from \"./typed-event-emitter.ts\";\n\nconst logger = loggerInstance.getChild(\"RoomStickyEvents\");\n\nexport enum RoomStickyEventsEvent {\n Update = \"RoomStickyEvents.Update\",\n}\n\nexport type StickyMatrixEvent = MatrixEvent & { unstableStickyExpiresAt: number };\n\nexport type RoomStickyEventsMap = {\n /**\n * Fires when any sticky event changes happen in a room.\n * @param added Any new sticky events with no predecessor events (matching sender, type, and sticky_key)\n * @param updated Any sticky events that supersede an existing event (matching sender, type, and sticky_key)\n * @param removed The events that were removed from the map due to expiry.\n */\n [RoomStickyEventsEvent.Update]: (\n added: StickyMatrixEvent[],\n updated: { current: StickyMatrixEvent; previous: StickyMatrixEvent }[],\n removed: StickyMatrixEvent[],\n ) => void;\n};\n\ntype UserId = `@${string}`;\n\nfunction assertIsUserId(value: unknown): asserts value is UserId {\n if (typeof value !== \"string\") throw new Error(\"Not a string\");\n if (!value.startsWith(\"@\")) throw new Error(\"Not a userId\");\n}\n\n/**\n * Tracks sticky events on behalf of one room, and fires an event\n * whenever a sticky event is updated or replaced.\n */\nexport class RoomStickyEventsStore extends TypedEventEmitter<RoomStickyEventsEvent, RoomStickyEventsMap> {\n /**\n * Sticky event map is a nested map of:\n * eventType -> `content.sticky_key sender` -> StickyMatrixEvent[]\n *\n * The events are ordered in latest to earliest expiry, so that the first event\n * in the array will always be the \"current\" one.\n */\n private readonly stickyEventsMap = new Map<string, Map<string, StickyMatrixEvent[]>>();\n /**\n * These are sticky events that have no sticky key and therefore exist outside the tuple\n * system above. They are just held in this Set until they expire.\n */\n private readonly unkeyedStickyEvents = new Set<StickyMatrixEvent>();\n\n private stickyEventTimer?: ReturnType<typeof setTimeout>;\n private nextStickyEventExpiryTs: number = Number.MAX_SAFE_INTEGER;\n\n /**\n * Sort two sticky events by order of expiry. This assumes the sticky events have the same\n * `type`, `sticky_key` and `sender`.\n * @returns A positive value if event A will expire sooner, or a negative value if event B will expire sooner.\n */\n private static sortStickyEvent(eventA: StickyMatrixEvent, eventB: StickyMatrixEvent): number {\n // Sticky events with the same key have to use the same expiration duration.\n // Hence, comparing via `origin_server_ts` yields the exact same result as comparing their expiration time.\n if (eventB.getTs() !== eventA.getTs()) {\n return eventB.getTs() - eventA.getTs();\n }\n\n if ((eventB.getId() ?? \"\") > (eventA.getId() ?? \"\")) {\n return 1;\n }\n\n // This should fail as we've got corruption in our sticky array.\n throw Error(\"Comparing two sticky events with the same event ID is not allowed.\");\n }\n\n /**\n * Generate the correct key for an event to be found in the inner maps of `stickyEventsMap`.\n * @param stickyKey The sticky key of an event.\n * @param sender The sender of the event.\n */\n private static stickyMapKey(stickyKey: string, sender: UserId): string {\n return `${stickyKey}${sender}`;\n }\n\n /**\n * Get all sticky events that are currently active.\n * @returns An iterable set of events.\n */\n public *getStickyEvents(): Iterable<StickyMatrixEvent> {\n yield* this.unkeyedStickyEvents;\n for (const innerMap of this.stickyEventsMap.values()) {\n // Inner map contains a map of sender+stickykeys => all sticky events\n for (const events of innerMap.values()) {\n // The first sticky event is the \"current\" one in the sticky map.\n yield events[0];\n }\n }\n }\n\n /**\n * Get an active sticky event that match the given `type`, `sender`, and `stickyKey`\n * @param type The event `type`.\n * @param sender The sender of the sticky event.\n * @param stickyKey The sticky key used by the event.\n * @returns A matching active sticky event, or undefined.\n */\n public getKeyedStickyEvent(sender: string, type: string, stickyKey: string): StickyMatrixEvent | undefined {\n assertIsUserId(sender);\n return this.stickyEventsMap.get(type)?.get(RoomStickyEventsStore.stickyMapKey(stickyKey, sender))?.[0];\n }\n\n /**\n * Get active sticky events without a sticky key that match the given `type` and `sender`.\n * @param type The event `type`.\n * @param sender The sender of the sticky event.\n * @returns An array of matching sticky events.\n */\n public getUnkeyedStickyEvent(sender: string, type: string): StickyMatrixEvent[] {\n return [...this.unkeyedStickyEvents].filter((ev) => ev.getType() === type && ev.getSender() === sender);\n }\n\n /**\n * Adds a sticky event into the local sticky event map.\n *\n * NOTE: This will not cause `RoomEvent.StickyEvents` to be emitted.\n *\n * @throws If the `event` does not contain valid sticky data.\n * @param event The MatrixEvent that contains sticky data.\n * @returns An object describing whether the event was added to the map,\n * and the previous event it may have replaced.\n */\n private addStickyEvent(event: MatrixEvent): { added: true; prevEvent?: StickyMatrixEvent } | { added: false } {\n const stickyKey = event.getContent().msc4354_sticky_key;\n if (typeof stickyKey !== \"string\" && stickyKey !== undefined) {\n throw new Error(`${event.getId()} is missing msc4354_sticky_key`);\n }\n\n // With this we have the guarantee, that all events in stickyEventsMap are correctly formatted\n if (event.unstableStickyExpiresAt === undefined) {\n throw new Error(`${event.getId()} is missing msc4354_sticky.duration_ms`);\n }\n const sender = event.getSender();\n const type = event.getType();\n assertIsUserId(sender);\n if (event.unstableStickyExpiresAt <= Date.now()) {\n logger.info(\"ignored sticky event with older expiration time than current time\", stickyKey);\n return { added: false };\n }\n\n // While we fully expect the server to always provide the correct value,\n // this is just insurance to protect against attacks on our Map.\n if (!sender.startsWith(\"@\")) {\n throw new Error(\"Expected sender to start with @\");\n }\n\n const stickyEvent = event as StickyMatrixEvent;\n\n if (stickyKey === undefined) {\n this.unkeyedStickyEvents.add(stickyEvent);\n // Recalculate the next expiry time.\n this.nextStickyEventExpiryTs = Math.min(event.unstableStickyExpiresAt, this.nextStickyEventExpiryTs);\n\n this.scheduleStickyTimer();\n return { added: true };\n }\n\n // Why this is safe:\n // A type may contain anything but the *sender* is tightly\n // constrained so that a key will always end with a @<user_id>\n // E.g. Where a malicious event type might be \"rtc.member.event@foo:bar\" the key becomes:\n // \"rtc.member.event.@foo:bar@bar:baz\"\n const innerMapKey = RoomStickyEventsStore.stickyMapKey(stickyKey, sender);\n const currentEventSet = [stickyEvent, ...(this.stickyEventsMap.get(type)?.get(innerMapKey) ?? [])].sort(\n RoomStickyEventsStore.sortStickyEvent,\n );\n if (!this.stickyEventsMap.has(type)) {\n this.stickyEventsMap.set(type, new Map());\n }\n this.stickyEventsMap.get(type)?.set(innerMapKey, currentEventSet);\n\n // Recalculate the next expiry time.\n this.nextStickyEventExpiryTs = Math.min(stickyEvent.unstableStickyExpiresAt, this.nextStickyEventExpiryTs);\n\n this.scheduleStickyTimer();\n return {\n added: currentEventSet[0] === stickyEvent,\n prevEvent: currentEventSet?.[1],\n };\n }\n\n /**\n * Add a series of sticky events, emitting `RoomEvent.StickyEvents` if any\n * changes were made.\n * @param events A set of new sticky events.\n */\n public addStickyEvents(events: MatrixEvent[]): void {\n const added: StickyMatrixEvent[] = [];\n const updated: { current: StickyMatrixEvent; previous: StickyMatrixEvent }[] = [];\n for (const event of events) {\n try {\n const result = this.addStickyEvent(event);\n if (result.added) {\n if (result.prevEvent) {\n // e is validated as a StickyMatrixEvent by virtue of `addStickyEvent` returning added: true.\n updated.push({ current: event as StickyMatrixEvent, previous: result.prevEvent });\n } else {\n added.push(event as StickyMatrixEvent);\n }\n }\n } catch (ex) {\n logger.warn(\"ignored invalid sticky event\", ex);\n }\n }\n if (added.length || updated.length) this.emit(RoomStickyEventsEvent.Update, added, updated, []);\n this.scheduleStickyTimer();\n }\n\n /**\n * Schedule the sticky event expiry timer. The timer will\n * run immediately if an event has already expired.\n */\n private scheduleStickyTimer(): void {\n if (this.stickyEventTimer) {\n clearTimeout(this.stickyEventTimer);\n this.stickyEventTimer = undefined;\n }\n if (this.nextStickyEventExpiryTs === Number.MAX_SAFE_INTEGER) {\n // We have no events due to expire.\n return;\n } // otherwise, schedule in the future\n this.stickyEventTimer = setTimeout(this.cleanExpiredStickyEvents, this.nextStickyEventExpiryTs - Date.now());\n }\n\n /**\n * Clean out any expired sticky events.\n */\n private readonly cleanExpiredStickyEvents = (): void => {\n const now = Date.now();\n const removedEvents: StickyMatrixEvent[] = [];\n\n // We will recalculate this as we check all events.\n this.nextStickyEventExpiryTs = Number.MAX_SAFE_INTEGER;\n for (const [eventType, innerEvents] of this.stickyEventsMap.entries()) {\n for (const [innerMapKey, [currentEvent, ...previousEvents]] of innerEvents) {\n // we only added items with `sticky` into this map so we can assert non-null here\n if (now >= currentEvent.unstableStickyExpiresAt) {\n logger.debug(\"Expiring sticky event\", currentEvent.getId());\n removedEvents.push(currentEvent);\n this.stickyEventsMap.get(eventType)!.delete(innerMapKey);\n } else {\n // Ensure we remove any previous events which have now expired, to avoid unbounded memory consumption.\n this.stickyEventsMap\n .get(eventType)!\n .set(innerMapKey, [\n currentEvent,\n ...previousEvents.filter((e) => e.unstableStickyExpiresAt <= now),\n ]);\n // If not removing the event, check to see if it's the next lowest expiry.\n this.nextStickyEventExpiryTs = Math.min(\n this.nextStickyEventExpiryTs,\n currentEvent.unstableStickyExpiresAt,\n );\n }\n }\n // Clean up map after use.\n if (this.stickyEventsMap.get(eventType)?.size === 0) {\n this.stickyEventsMap.delete(eventType);\n }\n }\n for (const event of this.unkeyedStickyEvents) {\n if (now >= event.unstableStickyExpiresAt) {\n logger.debug(\"Expiring sticky event\", event.getId());\n this.unkeyedStickyEvents.delete(event);\n removedEvents.push(event);\n } else {\n // If not removing the event, check to see if it's the next lowest expiry.\n this.nextStickyEventExpiryTs = Math.min(this.nextStickyEventExpiryTs, event.unstableStickyExpiresAt);\n }\n }\n if (removedEvents.length) {\n this.emit(RoomStickyEventsEvent.Update, [], [], removedEvents);\n }\n // Finally, schedule the next run.\n this.scheduleStickyTimer();\n };\n\n /**\n * Handles incoming event redactions. Checks the sticky map\n * for any active sticky events being redacted.\n * @param redactedEvent The MatrixEvent OR event ID of the event being redacted. MAY not be a sticky event.\n */\n public handleRedaction(redactedEvent: MatrixEvent | string): void {\n // Note, we do not adjust`nextStickyEventExpiryTs` here.\n // If this event happens to be the most recent expiring event\n // then we may do one extra iteration of cleanExpiredStickyEvents\n // but this saves us having to iterate over all events here to calculate\n // the next expiry time.\n\n // Note, as soon as we find a positive match on an event in this function\n // we can return. There is no need to continue iterating on a positive match\n // as an event can only appear in one map.\n\n // Handle unkeyedStickyEvents first since it's *quick*.\n const redactEventId = typeof redactedEvent === \"string\" ? redactedEvent : redactedEvent.getId();\n for (const event of this.unkeyedStickyEvents) {\n if (event.getId() === redactEventId) {\n this.unkeyedStickyEvents.delete(event);\n this.emit(RoomStickyEventsEvent.Update, [], [], [event]);\n return;\n }\n }\n\n // Faster method of finding the event since we have the event cached.\n if (typeof redactedEvent !== \"string\" && !redactedEvent.isRedacted()) {\n const stickyKey = redactedEvent.getContent().msc4354_sticky_key;\n if (typeof stickyKey !== \"string\" && stickyKey !== undefined) {\n return; // Not a sticky event.\n }\n const eventType = redactedEvent.getType();\n const sender = redactedEvent.getSender();\n assertIsUserId(sender);\n const innerMap = this.stickyEventsMap.get(eventType);\n if (!innerMap) {\n return;\n }\n const mapKey = RoomStickyEventsStore.stickyMapKey(stickyKey, sender);\n const [currentEvent, ...previousEvents] = innerMap.get(mapKey) ?? [];\n if (!currentEvent) {\n // No event current in the map so ignore.\n return;\n }\n logger.debug(`Redaction for ${redactEventId} under sticky key ${stickyKey}`);\n // Revert to previous state, taking care to skip any other redacted events.\n const newEvents = previousEvents.filter((e) => !e.isRedacted()).sort(RoomStickyEventsStore.sortStickyEvent);\n this.stickyEventsMap.get(eventType)?.set(mapKey, newEvents);\n if (newEvents.length) {\n this.emit(\n RoomStickyEventsEvent.Update,\n [],\n [\n {\n // This looks confusing. This emits that the newer event\n // has been redacted and the previous event has taken it's place.\n previous: currentEvent,\n current: newEvents[0],\n },\n ],\n [],\n );\n } else {\n // We did not find a previous event, so just expire.\n innerMap.delete(mapKey);\n if (innerMap.size === 0) {\n this.stickyEventsMap.delete(eventType);\n }\n this.emit(RoomStickyEventsEvent.Update, [], [], [currentEvent]);\n }\n return;\n }\n\n // We only know the event ID of the redacted event, so we need to\n // traverse the map to find our event.\n for (const innerMap of this.stickyEventsMap.values()) {\n for (const [currentEvent] of innerMap.values()) {\n if (currentEvent.getId() !== redactEventId) {\n continue;\n }\n // Found the event.\n return this.handleRedaction(currentEvent);\n }\n }\n }\n\n /**\n * Clear all events and stop the timer from firing.\n */\n public clear(): void {\n this.stickyEventsMap.clear();\n // Unschedule timer.\n this.nextStickyEventExpiryTs = Number.MAX_SAFE_INTEGER;\n this.scheduleStickyTimer();\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"room-sticky-events.js","names":["logger","loggerInstance","TypedEventEmitter","getChild","RoomStickyEventsEvent","assertIsUserId","value","Error","startsWith","RoomStickyEventsStore","constructor","arguments","_defineProperty","Map","Set","Number","MAX_SAFE_INTEGER","now","Date","removedEvents","nextStickyEventExpiryTs","_ref3","stickyEventsMap","entries","_this$stickyEventsMap","_ref2","_slicedToArray","eventType","innerEvents","_ref6","_ref5","innerMapKey","_ref5$","_toArray","currentEvent","previousEvents","_arrayLikeToArray","slice","unstableStickyExpiresAt","debug","getId","push","get","delete","set","filter","e","Math","min","size","event","unkeyedStickyEvents","length","emit","Update","scheduleStickyTimer","sortStickyEvent","eventA","eventB","_eventB$getId","_eventA$getId","getTs","stickyMapKey","stickyKey","sender","concat","getStickyEvents","innerMap","values","events","getKeyedStickyEvent","type","_this$stickyEventsMap2","getUnkeyedStickyEvent","ev","getType","getSender","addStickyEvent","_this$stickyEventsMap3","_this$stickyEventsMap4","_this$stickyEventsMap5","getContent","msc4354_sticky_key","undefined","info","added","stickyEvent","add","currentEventSet","sort","has","prevEvent","addStickyEvents","updated","result","current","previous","ex","warn","stickyEventTimer","clearTimeout","setTimeout","cleanExpiredStickyEvents","handleRedaction","redactedEvent","redactEventId","isRedacted","_innerMap$get","_this$stickyEventsMap6","mapKey","_ref7","_ref8","newEvents","_ref1","_ref0","clear"],"sources":["../../src/models/room-sticky-events.ts"],"sourcesContent":["import { logger as loggerInstance } from \"../logger.ts\";\nimport { type MatrixEvent } from \"./event.ts\";\nimport { TypedEventEmitter } from \"./typed-event-emitter.ts\";\n\nconst logger = loggerInstance.getChild(\"RoomStickyEvents\");\n\nexport enum RoomStickyEventsEvent {\n Update = \"RoomStickyEvents.Update\",\n}\n\nexport type StickyMatrixEvent = MatrixEvent & { unstableStickyExpiresAt: number };\n\nexport type RoomStickyEventsMap = {\n /**\n * Fires when any sticky event changes happen in a room.\n * @param added Any new sticky events with no predecessor events (matching sender, type, and sticky_key)\n * @param updated Any sticky events that supersede an existing event (matching sender, type, and sticky_key)\n * @param removed The events that were removed from the map due to expiry.\n */\n [RoomStickyEventsEvent.Update]: (\n added: StickyMatrixEvent[],\n updated: { current: StickyMatrixEvent; previous: StickyMatrixEvent }[],\n removed: StickyMatrixEvent[],\n ) => void;\n};\n\ntype UserId = `@${string}`;\n\nfunction assertIsUserId(value: unknown): asserts value is UserId {\n if (typeof value !== \"string\") throw new Error(\"Not a string\");\n if (!value.startsWith(\"@\")) throw new Error(\"Not a userId\");\n}\n\n/**\n * Tracks sticky events on behalf of one room, and fires an event\n * whenever a sticky event is updated or replaced.\n */\nexport class RoomStickyEventsStore extends TypedEventEmitter<RoomStickyEventsEvent, RoomStickyEventsMap> {\n /**\n * Sticky event map is a nested map of:\n * eventType -> `content.sticky_key sender` -> StickyMatrixEvent[]\n *\n * The events are ordered in latest to earliest expiry, so that the first event\n * in the array will always be the \"current\" one.\n */\n private readonly stickyEventsMap = new Map<string, Map<string, StickyMatrixEvent[]>>();\n /**\n * These are sticky events that have no sticky key and therefore exist outside the tuple\n * system above. They are just held in this Set until they expire.\n */\n private readonly unkeyedStickyEvents = new Set<StickyMatrixEvent>();\n\n private stickyEventTimer?: ReturnType<typeof setTimeout>;\n private nextStickyEventExpiryTs: number = Number.MAX_SAFE_INTEGER;\n\n /**\n * Sort two sticky events by order of expiry. This assumes the sticky events have the same\n * `type`, `sticky_key` and `sender`.\n * @returns A positive value if event A will expire sooner, or a negative value if event B will expire sooner.\n */\n private static sortStickyEvent(eventA: StickyMatrixEvent, eventB: StickyMatrixEvent): number {\n // Sticky events with the same key have to use the same expiration duration.\n // Hence, comparing via `origin_server_ts` yields the exact same result as comparing their expiration time.\n if (eventB.getTs() !== eventA.getTs()) {\n return eventB.getTs() - eventA.getTs();\n }\n\n if ((eventB.getId() ?? \"\") > (eventA.getId() ?? \"\")) {\n return 1;\n }\n\n // This should fail as we've got corruption in our sticky array.\n throw Error(\"Comparing two sticky events with the same event ID is not allowed.\");\n }\n\n /**\n * Generate the correct key for an event to be found in the inner maps of `stickyEventsMap`.\n * @param stickyKey The sticky key of an event.\n * @param sender The sender of the event.\n */\n private static stickyMapKey(stickyKey: string, sender: UserId): string {\n return `${stickyKey}${sender}`;\n }\n\n /**\n * Get all sticky events that are currently active.\n * @returns An iterable set of events.\n */\n public *getStickyEvents(): Iterable<StickyMatrixEvent> {\n yield* this.unkeyedStickyEvents;\n for (const innerMap of this.stickyEventsMap.values()) {\n // Inner map contains a map of sender+stickykeys => all sticky events\n for (const events of innerMap.values()) {\n // The first sticky event is the \"current\" one in the sticky map.\n yield events[0];\n }\n }\n }\n\n /**\n * Get an active sticky event that match the given `type`, `sender`, and `stickyKey`\n * @param type The event `type`.\n * @param sender The sender of the sticky event.\n * @param stickyKey The sticky key used by the event.\n * @returns A matching active sticky event, or undefined.\n */\n public getKeyedStickyEvent(sender: string, type: string, stickyKey: string): StickyMatrixEvent | undefined {\n assertIsUserId(sender);\n return this.stickyEventsMap.get(type)?.get(RoomStickyEventsStore.stickyMapKey(stickyKey, sender))?.[0];\n }\n\n /**\n * Get active sticky events without a sticky key that match the given `type` and `sender`.\n * @param type The event `type`.\n * @param sender The sender of the sticky event.\n * @returns An array of matching sticky events.\n */\n public getUnkeyedStickyEvent(sender: string, type: string): StickyMatrixEvent[] {\n return [...this.unkeyedStickyEvents].filter((ev) => ev.getType() === type && ev.getSender() === sender);\n }\n\n /**\n * Adds a sticky event into the local sticky event map.\n *\n * NOTE: This will not cause `RoomEvent.StickyEvents` to be emitted.\n *\n * @throws If the `event` does not contain valid sticky data.\n * @param event The MatrixEvent that contains sticky data.\n * @returns An object describing whether the event was added to the map,\n * and the previous event it may have replaced.\n */\n private addStickyEvent(event: MatrixEvent): { added: true; prevEvent?: StickyMatrixEvent } | { added: false } {\n const stickyKey = event.getContent().msc4354_sticky_key;\n if (typeof stickyKey !== \"string\" && stickyKey !== undefined) {\n throw new Error(`${event.getId()} is missing msc4354_sticky_key`);\n }\n\n // With this we have the guarantee, that all events in stickyEventsMap are correctly formatted\n if (event.unstableStickyExpiresAt === undefined) {\n throw new Error(`${event.getId()} is missing msc4354_sticky.duration_ms`);\n }\n const sender = event.getSender();\n const type = event.getType();\n assertIsUserId(sender);\n if (event.unstableStickyExpiresAt <= Date.now()) {\n logger.info(\"ignored sticky event with older expiration time than current time\", stickyKey);\n return { added: false };\n }\n\n // While we fully expect the server to always provide the correct value,\n // this is just insurance to protect against attacks on our Map.\n if (!sender.startsWith(\"@\")) {\n throw new Error(\"Expected sender to start with @\");\n }\n\n const stickyEvent = event as StickyMatrixEvent;\n\n if (stickyKey === undefined) {\n this.unkeyedStickyEvents.add(stickyEvent);\n // Recalculate the next expiry time.\n this.nextStickyEventExpiryTs = Math.min(event.unstableStickyExpiresAt, this.nextStickyEventExpiryTs);\n\n this.scheduleStickyTimer();\n return { added: true };\n }\n\n // Why this is safe:\n // A type may contain anything but the *sender* is tightly\n // constrained so that a key will always end with a @<user_id>\n // E.g. Where a malicious event type might be \"rtc.member.event@foo:bar\" the key becomes:\n // \"rtc.member.event.@foo:bar@bar:baz\"\n const innerMapKey = RoomStickyEventsStore.stickyMapKey(stickyKey, sender);\n const currentEventSet = [stickyEvent, ...(this.stickyEventsMap.get(type)?.get(innerMapKey) ?? [])].sort(\n RoomStickyEventsStore.sortStickyEvent,\n );\n if (!this.stickyEventsMap.has(type)) {\n this.stickyEventsMap.set(type, new Map());\n }\n this.stickyEventsMap.get(type)?.set(innerMapKey, currentEventSet);\n\n // Recalculate the next expiry time.\n this.nextStickyEventExpiryTs = Math.min(stickyEvent.unstableStickyExpiresAt, this.nextStickyEventExpiryTs);\n\n this.scheduleStickyTimer();\n return {\n added: currentEventSet[0] === stickyEvent,\n prevEvent: currentEventSet?.[1],\n };\n }\n\n /**\n * Add a series of sticky events, emitting `RoomEvent.StickyEvents` if any\n * changes were made.\n * @param events A set of new sticky events.\n */\n public addStickyEvents(events: MatrixEvent[]): void {\n const added: StickyMatrixEvent[] = [];\n const updated: { current: StickyMatrixEvent; previous: StickyMatrixEvent }[] = [];\n for (const event of events) {\n try {\n const result = this.addStickyEvent(event);\n if (result.added) {\n if (result.prevEvent) {\n // e is validated as a StickyMatrixEvent by virtue of `addStickyEvent` returning added: true.\n updated.push({ current: event as StickyMatrixEvent, previous: result.prevEvent });\n } else {\n added.push(event as StickyMatrixEvent);\n }\n }\n } catch (ex) {\n logger.warn(\"ignored invalid sticky event\", ex);\n }\n }\n if (added.length || updated.length) this.emit(RoomStickyEventsEvent.Update, added, updated, []);\n this.scheduleStickyTimer();\n }\n\n /**\n * Schedule the sticky event expiry timer. The timer will\n * run immediately if an event has already expired.\n */\n private scheduleStickyTimer(): void {\n if (this.stickyEventTimer) {\n clearTimeout(this.stickyEventTimer);\n this.stickyEventTimer = undefined;\n }\n if (this.nextStickyEventExpiryTs === Number.MAX_SAFE_INTEGER) {\n // We have no events due to expire.\n return;\n } // otherwise, schedule in the future\n this.stickyEventTimer = setTimeout(this.cleanExpiredStickyEvents, this.nextStickyEventExpiryTs - Date.now());\n }\n\n /**\n * Clean out any expired sticky events.\n */\n private readonly cleanExpiredStickyEvents = (): void => {\n const now = Date.now();\n const removedEvents: StickyMatrixEvent[] = [];\n\n // We will recalculate this as we check all events.\n this.nextStickyEventExpiryTs = Number.MAX_SAFE_INTEGER;\n for (const [eventType, innerEvents] of this.stickyEventsMap.entries()) {\n for (const [innerMapKey, [currentEvent, ...previousEvents]] of innerEvents) {\n // we only added items with `sticky` into this map so we can assert non-null here\n if (now >= currentEvent.unstableStickyExpiresAt) {\n logger.debug(\"Expiring sticky event\", currentEvent.getId());\n removedEvents.push(currentEvent);\n this.stickyEventsMap.get(eventType)!.delete(innerMapKey);\n } else {\n // Ensure we remove any previous events which have now expired, to avoid unbounded memory consumption.\n this.stickyEventsMap\n .get(eventType)!\n .set(innerMapKey, [\n currentEvent,\n ...previousEvents.filter((e) => e.unstableStickyExpiresAt <= now),\n ]);\n // If not removing the event, check to see if it's the next lowest expiry.\n this.nextStickyEventExpiryTs = Math.min(\n this.nextStickyEventExpiryTs,\n currentEvent.unstableStickyExpiresAt,\n );\n }\n }\n // Clean up map after use.\n if (this.stickyEventsMap.get(eventType)?.size === 0) {\n this.stickyEventsMap.delete(eventType);\n }\n }\n for (const event of this.unkeyedStickyEvents) {\n if (now >= event.unstableStickyExpiresAt) {\n logger.debug(\"Expiring sticky event\", event.getId());\n this.unkeyedStickyEvents.delete(event);\n removedEvents.push(event);\n } else {\n // If not removing the event, check to see if it's the next lowest expiry.\n this.nextStickyEventExpiryTs = Math.min(this.nextStickyEventExpiryTs, event.unstableStickyExpiresAt);\n }\n }\n if (removedEvents.length) {\n this.emit(RoomStickyEventsEvent.Update, [], [], removedEvents);\n }\n // Finally, schedule the next run.\n this.scheduleStickyTimer();\n };\n\n /**\n * Handles incoming event redactions. Checks the sticky map\n * for any active sticky events being redacted.\n * @param redactedEvent The MatrixEvent OR event ID of the event being redacted. MAY not be a sticky event.\n */\n public handleRedaction(redactedEvent: MatrixEvent | string): void {\n // Note, we do not adjust`nextStickyEventExpiryTs` here.\n // If this event happens to be the most recent expiring event\n // then we may do one extra iteration of cleanExpiredStickyEvents\n // but this saves us having to iterate over all events here to calculate\n // the next expiry time.\n\n // Note, as soon as we find a positive match on an event in this function\n // we can return. There is no need to continue iterating on a positive match\n // as an event can only appear in one map.\n\n // Handle unkeyedStickyEvents first since it's *quick*.\n const redactEventId = typeof redactedEvent === \"string\" ? redactedEvent : redactedEvent.getId();\n for (const event of this.unkeyedStickyEvents) {\n if (event.getId() === redactEventId) {\n this.unkeyedStickyEvents.delete(event);\n this.emit(RoomStickyEventsEvent.Update, [], [], [event]);\n return;\n }\n }\n\n // Faster method of finding the event since we have the event cached.\n if (typeof redactedEvent !== \"string\" && !redactedEvent.isRedacted()) {\n const stickyKey = redactedEvent.getContent().msc4354_sticky_key;\n if (typeof stickyKey !== \"string\" && stickyKey !== undefined) {\n return; // Not a sticky event.\n }\n const eventType = redactedEvent.getType();\n const sender = redactedEvent.getSender();\n assertIsUserId(sender);\n const innerMap = this.stickyEventsMap.get(eventType);\n if (!innerMap) {\n return;\n }\n const mapKey = RoomStickyEventsStore.stickyMapKey(stickyKey, sender);\n const [currentEvent, ...previousEvents] = innerMap.get(mapKey) ?? [];\n if (!currentEvent) {\n // No event current in the map so ignore.\n return;\n }\n logger.debug(`Redaction for ${redactEventId} under sticky key ${stickyKey}`);\n // Revert to previous state, taking care to skip any other redacted events.\n const newEvents = previousEvents.filter((e) => !e.isRedacted()).sort(RoomStickyEventsStore.sortStickyEvent);\n this.stickyEventsMap.get(eventType)?.set(mapKey, newEvents);\n if (newEvents.length) {\n this.emit(\n RoomStickyEventsEvent.Update,\n [],\n [\n {\n // This looks confusing. This emits that the newer event\n // has been redacted and the previous event has taken it's place.\n previous: currentEvent,\n current: newEvents[0],\n },\n ],\n [],\n );\n } else {\n // We did not find a previous event, so just expire.\n innerMap.delete(mapKey);\n if (innerMap.size === 0) {\n this.stickyEventsMap.delete(eventType);\n }\n this.emit(RoomStickyEventsEvent.Update, [], [], [currentEvent]);\n }\n return;\n }\n\n // We only know the event ID of the redacted event, so we need to\n // traverse the map to find our event.\n for (const innerMap of this.stickyEventsMap.values()) {\n for (const [currentEvent] of innerMap.values()) {\n if (currentEvent.getId() !== redactEventId) {\n continue;\n }\n // Found the event.\n return this.handleRedaction(currentEvent);\n }\n }\n }\n\n /**\n * Clear all events and stop the timer from firing.\n */\n public clear(): void {\n this.stickyEventsMap.clear();\n // Unschedule timer.\n this.nextStickyEventExpiryTs = Number.MAX_SAFE_INTEGER;\n this.scheduleStickyTimer();\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
package/lib/models/room.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
1
2
|
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
3
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
3
4
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
@@ -124,11 +125,6 @@ export class Room extends ReadReceipt {
|
|
|
124
125
|
// common to have quite a few more than the default limit.
|
|
125
126
|
super();
|
|
126
127
|
_this = this;
|
|
127
|
-
this.roomId = roomId;
|
|
128
|
-
this.client = client;
|
|
129
|
-
this.myUserId = myUserId;
|
|
130
|
-
this.opts = opts;
|
|
131
|
-
_defineProperty(this, "reEmitter", void 0);
|
|
132
128
|
_defineProperty(this, "txnToEvent", new Map());
|
|
133
129
|
// Pending in-flight requests { string: MatrixEvent }
|
|
134
130
|
_defineProperty(this, "notificationCounts", {});
|
|
@@ -142,7 +138,6 @@ export class Room extends ReadReceipt {
|
|
|
142
138
|
* This is useful in determining whether a user has read a thread or not
|
|
143
139
|
*/
|
|
144
140
|
_defineProperty(this, "unthreadedReceipts", new Map());
|
|
145
|
-
_defineProperty(this, "timelineSets", void 0);
|
|
146
141
|
_defineProperty(this, "polls", new Map());
|
|
147
142
|
/**
|
|
148
143
|
* Empty array if the timeline sets have not been initialised. After initialisation:
|
|
@@ -154,10 +149,6 @@ export class Room extends ReadReceipt {
|
|
|
154
149
|
_defineProperty(this, "filteredTimelineSets", {});
|
|
155
150
|
// filter_id: timelineSet
|
|
156
151
|
_defineProperty(this, "timelineNeedsRefresh", false);
|
|
157
|
-
_defineProperty(this, "pendingEventList", void 0);
|
|
158
|
-
// read by megolm via getter; boolean value - null indicates "use global value"
|
|
159
|
-
_defineProperty(this, "blacklistUnverifiedDevices", void 0);
|
|
160
|
-
_defineProperty(this, "selfMembership", void 0);
|
|
161
152
|
/**
|
|
162
153
|
* A `Hero` is a stripped `m.room.member` event which contains the important renderable fields from the event.
|
|
163
154
|
*
|
|
@@ -170,16 +161,6 @@ export class Room extends ReadReceipt {
|
|
|
170
161
|
_defineProperty(this, "heroes", null);
|
|
171
162
|
// flags to stop logspam about missing m.room.create events
|
|
172
163
|
_defineProperty(this, "getTypeWarning", false);
|
|
173
|
-
_defineProperty(this, "membersPromise", void 0);
|
|
174
|
-
// XXX: These should be read-only
|
|
175
|
-
/**
|
|
176
|
-
* The human-readable display name for this room.
|
|
177
|
-
*/
|
|
178
|
-
_defineProperty(this, "name", void 0);
|
|
179
|
-
/**
|
|
180
|
-
* The un-homoglyphed name for this room.
|
|
181
|
-
*/
|
|
182
|
-
_defineProperty(this, "normalizedName", void 0);
|
|
183
164
|
/**
|
|
184
165
|
* Dict of room tags; the keys are the tag name and the values
|
|
185
166
|
* are any metadata associated with the tag - e.g. `{ "fav" : { order: 1 } }`
|
|
@@ -196,21 +177,6 @@ export class Room extends ReadReceipt {
|
|
|
196
177
|
* The room summary.
|
|
197
178
|
*/
|
|
198
179
|
_defineProperty(this, "summary", null);
|
|
199
|
-
/**
|
|
200
|
-
* oldState The state of the room at the time of the oldest event in the live timeline.
|
|
201
|
-
*
|
|
202
|
-
* @deprecated Present for backwards compatibility.
|
|
203
|
-
* Use getLiveTimeline().getState(EventTimeline.BACKWARDS) instead
|
|
204
|
-
*/
|
|
205
|
-
_defineProperty(this, "oldState", void 0);
|
|
206
|
-
/**
|
|
207
|
-
* currentState The state of the room at the time of the newest event in the timeline.
|
|
208
|
-
*
|
|
209
|
-
* @deprecated Present for backwards compatibility.
|
|
210
|
-
* Use getLiveTimeline().getState(EventTimeline.FORWARDS) instead.
|
|
211
|
-
*/
|
|
212
|
-
_defineProperty(this, "currentState", void 0);
|
|
213
|
-
_defineProperty(this, "relations", void 0);
|
|
214
180
|
/**
|
|
215
181
|
* A collection of events known by the client
|
|
216
182
|
* This is not a comprehensive list of the threads that exist in this room
|
|
@@ -328,6 +294,10 @@ export class Room extends ReadReceipt {
|
|
|
328
294
|
}
|
|
329
295
|
}
|
|
330
296
|
});
|
|
297
|
+
this.roomId = roomId;
|
|
298
|
+
this.client = client;
|
|
299
|
+
this.myUserId = myUserId;
|
|
300
|
+
this.opts = opts;
|
|
331
301
|
this.setMaxListeners(100);
|
|
332
302
|
this.reEmitter = new TypedReEmitter(this);
|
|
333
303
|
opts.pendingEventOrdering = opts.pendingEventOrdering || PendingEventOrdering.Chronological;
|
|
@@ -1131,10 +1101,16 @@ export class Room extends ReadReceipt {
|
|
|
1131
1101
|
var hasUnthreadedReceipt = false;
|
|
1132
1102
|
var content = event.getContent();
|
|
1133
1103
|
for (var receiptGroup of Object.values(content)) {
|
|
1134
|
-
for (var
|
|
1104
|
+
for (var _ref4 of Object.entries(receiptGroup)) {
|
|
1105
|
+
var _ref3 = _slicedToArray(_ref4, 2);
|
|
1106
|
+
var receiptType = _ref3[0];
|
|
1107
|
+
var userReceipt = _ref3[1];
|
|
1135
1108
|
if (!utils.isSupportedReceiptType(receiptType)) continue;
|
|
1136
1109
|
if (!userReceipt) continue;
|
|
1137
|
-
for (var
|
|
1110
|
+
for (var _ref7 of Object.entries(userReceipt)) {
|
|
1111
|
+
var _ref6 = _slicedToArray(_ref7, 2);
|
|
1112
|
+
var userId = _ref6[0];
|
|
1113
|
+
var singleReceipt = _ref6[1];
|
|
1138
1114
|
if (!singleReceipt || typeof singleReceipt !== "object") continue;
|
|
1139
1115
|
var typedSingleReceipt = singleReceipt;
|
|
1140
1116
|
if (userId !== this.client.getUserId()) continue;
|
|
@@ -1290,11 +1266,11 @@ export class Room extends ReadReceipt {
|
|
|
1290
1266
|
* Get the notification for the event context (room or thread timeline)
|
|
1291
1267
|
*/
|
|
1292
1268
|
getUnreadCountForEventContext() {
|
|
1293
|
-
var
|
|
1269
|
+
var _ref8;
|
|
1294
1270
|
var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : NotificationCountType.Total;
|
|
1295
1271
|
var event = arguments.length > 1 ? arguments[1] : undefined;
|
|
1296
1272
|
var isThreadEvent = !!event.threadRootId && !event.isThreadRoot;
|
|
1297
|
-
return (
|
|
1273
|
+
return (_ref8 = isThreadEvent ? this.getThreadUnreadNotificationCount(event.threadRootId, type) : this.getRoomUnreadNotificationCount(type)) !== null && _ref8 !== void 0 ? _ref8 : 0;
|
|
1298
1274
|
}
|
|
1299
1275
|
|
|
1300
1276
|
/**
|
|
@@ -1387,7 +1363,10 @@ export class Room extends ReadReceipt {
|
|
|
1387
1363
|
resetThreadUnreadNotificationCountFromSync() {
|
|
1388
1364
|
var exceptThreadIds = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
1389
1365
|
var isEncrypted = this.hasEncryptionStateEvent();
|
|
1390
|
-
for (var
|
|
1366
|
+
for (var _ref1 of this.threadNotifications) {
|
|
1367
|
+
var _ref0 = _slicedToArray(_ref1, 2);
|
|
1368
|
+
var threadId = _ref0[0];
|
|
1369
|
+
var notifs = _ref0[1];
|
|
1391
1370
|
if (!exceptThreadIds.includes(threadId)) {
|
|
1392
1371
|
notifs.total = 0;
|
|
1393
1372
|
if (!isEncrypted) {
|
|
@@ -1736,11 +1715,13 @@ export class Room extends ReadReceipt {
|
|
|
1736
1715
|
* @returns The timelineSet
|
|
1737
1716
|
*/
|
|
1738
1717
|
getOrCreateFilteredTimelineSet(filter) {
|
|
1739
|
-
var {
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1718
|
+
var _ref10 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
|
1719
|
+
_ref10$prepopulateTim = _ref10.prepopulateTimeline,
|
|
1720
|
+
prepopulateTimeline = _ref10$prepopulateTim === void 0 ? true : _ref10$prepopulateTim,
|
|
1721
|
+
_ref10$useSyncEvents = _ref10.useSyncEvents,
|
|
1722
|
+
useSyncEvents = _ref10$useSyncEvents === void 0 ? true : _ref10$useSyncEvents,
|
|
1723
|
+
_ref10$pendingEvents = _ref10.pendingEvents,
|
|
1724
|
+
pendingEvents = _ref10$pendingEvents === void 0 ? true : _ref10$pendingEvents;
|
|
1744
1725
|
if (this.filteredTimelineSets[filter.filterId]) {
|
|
1745
1726
|
return this.filteredTimelineSets[filter.filterId];
|
|
1746
1727
|
}
|
|
@@ -1836,8 +1817,9 @@ export class Room extends ReadReceipt {
|
|
|
1836
1817
|
timelineSet = new EventTimelineSet(_this10, {
|
|
1837
1818
|
pendingEvents: false
|
|
1838
1819
|
});
|
|
1839
|
-
Array.from(_this10.threads).forEach(
|
|
1840
|
-
var
|
|
1820
|
+
Array.from(_this10.threads).forEach(_ref11 => {
|
|
1821
|
+
var _ref12 = _slicedToArray(_ref11, 2),
|
|
1822
|
+
thread = _ref12[1];
|
|
1841
1823
|
if (thread.length === 0) return;
|
|
1842
1824
|
var currentUserParticipated = thread.timeline.some(event => {
|
|
1843
1825
|
return event.getSender() === _this10.client.getUserId();
|
|
@@ -1881,9 +1863,8 @@ export class Room extends ReadReceipt {
|
|
|
1881
1863
|
yield Promise.all([_this11.fetchRoomThreadList(ThreadFilterType.All), _this11.fetchRoomThreadList(ThreadFilterType.My)]);
|
|
1882
1864
|
} else {
|
|
1883
1865
|
var allThreadsFilter = yield _this11.getThreadListFilter();
|
|
1884
|
-
var
|
|
1885
|
-
chunk
|
|
1886
|
-
} = yield _this11.client.createMessagesRequest(_this11.roomId, "", Number.MAX_SAFE_INTEGER, Direction.Backward, allThreadsFilter);
|
|
1866
|
+
var _yield$_this11$client = yield _this11.client.createMessagesRequest(_this11.roomId, "", Number.MAX_SAFE_INTEGER, Direction.Backward, allThreadsFilter),
|
|
1867
|
+
events = _yield$_this11$client.chunk;
|
|
1887
1868
|
if (!events.length) return;
|
|
1888
1869
|
|
|
1889
1870
|
// Sorted by last_reply origin_server_ts
|
|
@@ -2006,10 +1987,9 @@ export class Room extends ReadReceipt {
|
|
|
2006
1987
|
if (!_this14.client.supportsThreads()) return;
|
|
2007
1988
|
if (_this14.threadsTimelineSets.length === 0) return;
|
|
2008
1989
|
var timelineSet = filter === ThreadFilterType.My ? _this14.threadsTimelineSets[1] : _this14.threadsTimelineSets[0];
|
|
2009
|
-
var
|
|
2010
|
-
chunk
|
|
2011
|
-
end
|
|
2012
|
-
} = yield _this14.client.createThreadListMessagesRequest(_this14.roomId, null, undefined, Direction.Backward, timelineSet.threadListType, timelineSet.getFilter());
|
|
1990
|
+
var _yield$_this14$client = yield _this14.client.createThreadListMessagesRequest(_this14.roomId, null, undefined, Direction.Backward, timelineSet.threadListType, timelineSet.getFilter()),
|
|
1991
|
+
events = _yield$_this14$client.chunk,
|
|
1992
|
+
end = _yield$_this14$client.end;
|
|
2013
1993
|
timelineSet.getLiveTimeline().setPaginationToken(end !== null && end !== void 0 ? end : null, Direction.Backward);
|
|
2014
1994
|
if (!events.length) return;
|
|
2015
1995
|
var matrixEvents = events.map(_this14.client.getEventMapper());
|
|
@@ -2142,9 +2122,8 @@ export class Room extends ReadReceipt {
|
|
|
2142
2122
|
}
|
|
2143
2123
|
findThreadForEvent(event) {
|
|
2144
2124
|
if (!event) return null;
|
|
2145
|
-
var
|
|
2146
|
-
threadId
|
|
2147
|
-
} = this.eventShouldLiveIn(event);
|
|
2125
|
+
var _this$eventShouldLive = this.eventShouldLiveIn(event),
|
|
2126
|
+
threadId = _this$eventShouldLive.threadId;
|
|
2148
2127
|
return threadId ? this.getThread(threadId) : null;
|
|
2149
2128
|
}
|
|
2150
2129
|
addThreadedEvents(threadId, events) {
|
|
@@ -2167,17 +2146,18 @@ export class Room extends ReadReceipt {
|
|
|
2167
2146
|
var eventsByThread = {};
|
|
2168
2147
|
for (var event of events) {
|
|
2169
2148
|
var _eventsByThread;
|
|
2170
|
-
var
|
|
2171
|
-
threadId,
|
|
2172
|
-
shouldLiveInThread
|
|
2173
|
-
} = this.eventShouldLiveIn(event);
|
|
2149
|
+
var _this$eventShouldLive2 = this.eventShouldLiveIn(event),
|
|
2150
|
+
threadId = _this$eventShouldLive2.threadId,
|
|
2151
|
+
shouldLiveInThread = _this$eventShouldLive2.shouldLiveInThread;
|
|
2174
2152
|
if (shouldLiveInThread && !eventsByThread[threadId]) {
|
|
2175
2153
|
eventsByThread[threadId] = [];
|
|
2176
2154
|
}
|
|
2177
2155
|
(_eventsByThread = eventsByThread[threadId]) === null || _eventsByThread === void 0 || _eventsByThread.push(event);
|
|
2178
2156
|
}
|
|
2179
|
-
Object.entries(eventsByThread).map(
|
|
2180
|
-
var
|
|
2157
|
+
Object.entries(eventsByThread).map(_ref13 => {
|
|
2158
|
+
var _ref14 = _slicedToArray(_ref13, 2),
|
|
2159
|
+
threadId = _ref14[0],
|
|
2160
|
+
threadEvents = _ref14[1];
|
|
2181
2161
|
return this.addThreadedEvents(threadId, threadEvents, toStartOfTimeline);
|
|
2182
2162
|
});
|
|
2183
2163
|
}
|
|
@@ -2288,7 +2268,10 @@ export class Room extends ReadReceipt {
|
|
|
2288
2268
|
var txnId = event.getUnsigned().transaction_id;
|
|
2289
2269
|
if (!txnId && event.getSender() === this.myUserId) {
|
|
2290
2270
|
// check the txn map for a matching event ID
|
|
2291
|
-
for (var
|
|
2271
|
+
for (var _ref17 of this.txnToEvent) {
|
|
2272
|
+
var _ref16 = _slicedToArray(_ref17, 2);
|
|
2273
|
+
var tid = _ref16[0];
|
|
2274
|
+
var localEvent = _ref16[1];
|
|
2292
2275
|
if (localEvent.getId() === event.getId()) {
|
|
2293
2276
|
logger.debug("processLiveEvent: found sent event without txn ID: ", tid, event.getId());
|
|
2294
2277
|
// update the unsigned field so we can re-use the same codepaths
|
|
@@ -2313,12 +2296,10 @@ export class Room extends ReadReceipt {
|
|
|
2313
2296
|
* Fires {@link RoomEvent.Timeline}
|
|
2314
2297
|
*/
|
|
2315
2298
|
addLiveEvent(event, addLiveEventOptions) {
|
|
2316
|
-
var
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
addToState
|
|
2321
|
-
} = addLiveEventOptions;
|
|
2299
|
+
var duplicateStrategy = addLiveEventOptions.duplicateStrategy,
|
|
2300
|
+
timelineWasEmpty = addLiveEventOptions.timelineWasEmpty,
|
|
2301
|
+
fromCache = addLiveEventOptions.fromCache,
|
|
2302
|
+
addToState = addLiveEventOptions.addToState;
|
|
2322
2303
|
|
|
2323
2304
|
// add to our timeline sets
|
|
2324
2305
|
for (var timelineSet of this.timelineSets) {
|
|
@@ -2500,10 +2481,9 @@ export class Room extends ReadReceipt {
|
|
|
2500
2481
|
// replace the event source (this will preserve the plaintext payload if
|
|
2501
2482
|
// any, which is good, because we don't want to try decoding it again).
|
|
2502
2483
|
localEvent.handleRemoteEcho(remoteEvent.event);
|
|
2503
|
-
var
|
|
2504
|
-
shouldLiveInRoom,
|
|
2505
|
-
threadId
|
|
2506
|
-
} = this.eventShouldLiveIn(remoteEvent);
|
|
2484
|
+
var _this$eventShouldLive3 = this.eventShouldLiveIn(remoteEvent),
|
|
2485
|
+
shouldLiveInRoom = _this$eventShouldLive3.shouldLiveInRoom,
|
|
2486
|
+
threadId = _this$eventShouldLive3.threadId;
|
|
2507
2487
|
var thread = threadId ? this.getThread(threadId) : null;
|
|
2508
2488
|
thread === null || thread === void 0 || thread.setEventMetadata(localEvent);
|
|
2509
2489
|
thread === null || thread === void 0 || thread.timelineSet.handleRemoteEcho(localEvent, oldEventId, newEventId);
|
|
@@ -2574,10 +2554,9 @@ export class Room extends ReadReceipt {
|
|
|
2574
2554
|
if (newStatus == EventStatus.SENT) {
|
|
2575
2555
|
// update the event id
|
|
2576
2556
|
event.replaceLocalEventId(newEventId);
|
|
2577
|
-
var
|
|
2578
|
-
shouldLiveInRoom,
|
|
2579
|
-
threadId
|
|
2580
|
-
} = this.eventShouldLiveIn(event);
|
|
2557
|
+
var _this$eventShouldLive4 = this.eventShouldLiveIn(event),
|
|
2558
|
+
shouldLiveInRoom = _this$eventShouldLive4.shouldLiveInRoom,
|
|
2559
|
+
threadId = _this$eventShouldLive4.threadId;
|
|
2581
2560
|
var thread = threadId ? this.getThread(threadId) : undefined;
|
|
2582
2561
|
thread === null || thread === void 0 || thread.setEventMetadata(event);
|
|
2583
2562
|
thread === null || thread === void 0 || thread.timelineSet.replaceEventId(oldEventId, newEventId);
|
|
@@ -2643,12 +2622,11 @@ export class Room extends ReadReceipt {
|
|
|
2643
2622
|
addLiveEvents(events, addLiveEventOptions) {
|
|
2644
2623
|
var _this15 = this;
|
|
2645
2624
|
return _asyncToGenerator(function* () {
|
|
2646
|
-
var
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
timelineWasEmpty = false
|
|
2650
|
-
addToState
|
|
2651
|
-
} = addLiveEventOptions;
|
|
2625
|
+
var duplicateStrategy = addLiveEventOptions.duplicateStrategy,
|
|
2626
|
+
fromCache = addLiveEventOptions.fromCache,
|
|
2627
|
+
_addLiveEventOptions$ = addLiveEventOptions.timelineWasEmpty,
|
|
2628
|
+
timelineWasEmpty = _addLiveEventOptions$ === void 0 ? false : _addLiveEventOptions$,
|
|
2629
|
+
addToState = addLiveEventOptions.addToState;
|
|
2652
2630
|
if (duplicateStrategy && ["replace", "ignore"].indexOf(duplicateStrategy) === -1) {
|
|
2653
2631
|
throw new Error("duplicateStrategy MUST be either 'replace' or 'ignore'");
|
|
2654
2632
|
}
|
|
@@ -2678,11 +2656,11 @@ export class Room extends ReadReceipt {
|
|
|
2678
2656
|
continue; // we can skip adding the event to the timeline sets, it is already there
|
|
2679
2657
|
}
|
|
2680
2658
|
}
|
|
2681
|
-
var
|
|
2682
|
-
shouldLiveInRoom,
|
|
2683
|
-
shouldLiveInThread,
|
|
2684
|
-
|
|
2685
|
-
|
|
2659
|
+
var _this15$eventShouldLi = _this15.eventShouldLiveIn(event, neighbouringEvents, threadRoots),
|
|
2660
|
+
shouldLiveInRoom = _this15$eventShouldLi.shouldLiveInRoom,
|
|
2661
|
+
shouldLiveInThread = _this15$eventShouldLi.shouldLiveInThread,
|
|
2662
|
+
_this15$eventShouldLi2 = _this15$eventShouldLi.threadId,
|
|
2663
|
+
threadId = _this15$eventShouldLi2 === void 0 ? "" : _this15$eventShouldLi2;
|
|
2686
2664
|
if (!shouldLiveInThread && !shouldLiveInRoom && event.isRelation()) {
|
|
2687
2665
|
try {
|
|
2688
2666
|
var parentEvent = new MatrixEvent(yield _this15.client.fetchRoomEvent(_this15.roomId, event.relationEventId));
|
|
@@ -2693,11 +2671,11 @@ export class Room extends ReadReceipt {
|
|
|
2693
2671
|
unsigned[UNSIGNED_THREAD_ID_FIELD.name] = parentEvent.threadRootId;
|
|
2694
2672
|
event.setUnsigned(unsigned);
|
|
2695
2673
|
}
|
|
2696
|
-
(
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2674
|
+
var _this15$eventShouldLi3 = _this15.eventShouldLiveIn(event, neighbouringEvents, threadRoots);
|
|
2675
|
+
shouldLiveInRoom = _this15$eventShouldLi3.shouldLiveInRoom;
|
|
2676
|
+
shouldLiveInThread = _this15$eventShouldLi3.shouldLiveInThread;
|
|
2677
|
+
var _this15$eventShouldLi4 = _this15$eventShouldLi3.threadId;
|
|
2678
|
+
threadId = _this15$eventShouldLi4 === void 0 ? "" : _this15$eventShouldLi4;
|
|
2701
2679
|
} catch (e) {
|
|
2702
2680
|
logger.error("Failed to load parent event of unhandled relation", e);
|
|
2703
2681
|
}
|
|
@@ -2712,8 +2690,10 @@ export class Room extends ReadReceipt {
|
|
|
2712
2690
|
_this15.relations.aggregateChildEvent(event);
|
|
2713
2691
|
}
|
|
2714
2692
|
}
|
|
2715
|
-
Object.entries(eventsByThread).forEach(
|
|
2716
|
-
var
|
|
2693
|
+
Object.entries(eventsByThread).forEach(_ref18 => {
|
|
2694
|
+
var _ref19 = _slicedToArray(_ref18, 2),
|
|
2695
|
+
threadId = _ref19[0],
|
|
2696
|
+
threadEvents = _ref19[1];
|
|
2717
2697
|
_this15.addThreadedEvents(threadId, threadEvents, false);
|
|
2718
2698
|
});
|
|
2719
2699
|
})();
|
|
@@ -2726,11 +2706,10 @@ export class Room extends ReadReceipt {
|
|
|
2726
2706
|
if (this.client.supportsThreads()) {
|
|
2727
2707
|
var threadRoots = this.findThreadRoots(events);
|
|
2728
2708
|
return events.reduce((memo, event) => {
|
|
2729
|
-
var
|
|
2730
|
-
shouldLiveInRoom,
|
|
2731
|
-
shouldLiveInThread,
|
|
2732
|
-
threadId
|
|
2733
|
-
} = this.eventShouldLiveIn(event, events, threadRoots);
|
|
2709
|
+
var _this$eventShouldLive5 = this.eventShouldLiveIn(event, events, threadRoots),
|
|
2710
|
+
shouldLiveInRoom = _this$eventShouldLive5.shouldLiveInRoom,
|
|
2711
|
+
shouldLiveInThread = _this$eventShouldLive5.shouldLiveInThread,
|
|
2712
|
+
threadId = _this$eventShouldLive5.threadId;
|
|
2734
2713
|
if (shouldLiveInRoom) {
|
|
2735
2714
|
memo[ROOM].push(event);
|
|
2736
2715
|
}
|
|
@@ -3215,10 +3194,8 @@ export class Room extends ReadReceipt {
|
|
|
3215
3194
|
var otherMembers = this.currentState.getMembers().filter(m => {
|
|
3216
3195
|
return m.userId !== userId && (m.membership === KnownMembership.Invite || m.membership === KnownMembership.Join);
|
|
3217
3196
|
});
|
|
3218
|
-
otherMembers = otherMembers.filter(
|
|
3219
|
-
var
|
|
3220
|
-
userId
|
|
3221
|
-
} = _ref6;
|
|
3197
|
+
otherMembers = otherMembers.filter(_ref20 => {
|
|
3198
|
+
var userId = _ref20.userId;
|
|
3222
3199
|
// filter service members
|
|
3223
3200
|
if (excludedUserIds.includes(userId)) {
|
|
3224
3201
|
inviteJoinCount--;
|