Convert WeakMaps to private fields

This commit is contained in:
hensm
2020-02-21 14:18:06 +00:00
parent f373374680
commit e4cc88ec1e
2 changed files with 212 additions and 253 deletions

View File

@@ -23,7 +23,7 @@ import { ListenerObject
, onMessage , onMessage
, sendMessageResponse } from "../../eventMessageChannel"; , sendMessageResponse } from "../../eventMessageChannel";
import { CallbacksMap import { Callbacks
, ErrorCallback , ErrorCallback
, LoadSuccessCallback , LoadSuccessCallback
, MediaListener , MediaListener
@@ -32,22 +32,175 @@ import { CallbacksMap
, UpdateListener } from "../../types"; , UpdateListener } from "../../types";
const _id = new WeakMap<Session, string>(); type SessionSuccessCallback = (session: Session) => void;
const _listener = new WeakMap<Session, ListenerObject>();
const _messageListeners = new WeakMap<
Session, Map<string, Set<MessageListener>>>();
const _updateListeners = new WeakMap<Session, Set<UpdateListener>>();
const _leaveCallbacks = new WeakMap<Session, CallbacksMap>();
const _sendMessageCallbacks = new WeakMap<Session, CallbacksMap>();
const _setReceiverMutedCallbacks = new WeakMap<Session, CallbacksMap>();
const _setReceiverVolumeLevelCallbacks = new WeakMap<Session, CallbacksMap>();
const _stopCallbacks = new WeakMap<Session, CallbacksMap>();
export default class Session { export default class Session {
#id = uuid();
#successCallback?: SessionSuccessCallback;
#messageListeners = new Map<string, Set<MessageListener>>();
#updateListeners = new Set<UpdateListener>();
#leaveCallbacks = new Map<string, Callbacks>();
#sendMessageCallbacks = new Map<string, Callbacks>();
#setReceiverMutedCallbacks = new Map<string, Callbacks>();
#setReceiverVolumeLevelCallbacks = new Map<string, Callbacks>();
#stopCallbacks = new Map<string, Callbacks>();
#listener = onMessage(message => {
// Filter other session messages
if ((message as any)._id !== this.#id) {
return;
}
switch (message.subject) {
case "shim:/session/stopped": {
// Disconnect from extension messages
this.#listener.disconnect();
this.status = SessionStatus.STOPPED;
for (const listener of this.#updateListeners) {
listener(false);
}
break;
}
case "shim:/session/connected": {
this.status = SessionStatus.CONNECTED;
this.sessionId = message.data.sessionId;
this.transportId = message.data.sessionId;
this.namespaces = message.data.namespaces;
this.displayName = message.data.displayName;
this.statusText = message.data.statusText;
if (this.#successCallback) {
this.#successCallback(this);
}
break;
}
case "shim:/session/updateStatus": {
const volume: Volume = message.data.volume;
if (volume) {
if (!this.receiver.volume) {
const receiverVolume = new Volume(
volume.level
, volume.muted);
receiverVolume.controlType = volume.controlType;
receiverVolume.stepInterval = volume.stepInterval;
this.receiver.volume = receiverVolume;
} else {
this.receiver.volume.level = volume.level;
this.receiver.volume.muted = volume.muted;
}
}
for (const listener of this.#updateListeners) {
listener(true);
}
break;
}
case "shim:/session/impl_addMessageListener": {
const { namespace, data } = message.data;
const messageListeners = this.#messageListeners.get(namespace);
if (messageListeners) {
for (const listener of messageListeners) {
listener(namespace, data);
}
}
break;
}
case "shim:/session/impl_sendMessage": {
const { messageId, error } = message.data;
const [ successCallback, errorCallback ] =
this.#sendMessageCallbacks.get(messageId) ?? [];
if (error && errorCallback) {
errorCallback(new _Error(ErrorCode.SESSION_ERROR));
} else if (successCallback) {
successCallback();
}
this.#sendMessageCallbacks.delete(messageId);
break;
}
case "shim:/session/impl_setReceiverMuted": {
const { volumeId, error } = message.data;
const [ successCallback, errorCallback ] =
this.#setReceiverMutedCallbacks.get(volumeId) ?? [];
if (error && errorCallback) {
errorCallback(new _Error(ErrorCode.SESSION_ERROR));
} else if (successCallback) {
successCallback();
}
this.#setReceiverMutedCallbacks.delete(volumeId);
break;
}
case "shim:/session/impl_setReceiverVolumeLevel": {
const { volumeId, error } = message.data;
const [ successCallback, errorCallback ] =
this.#setReceiverVolumeLevelCallbacks
.get(volumeId) ?? [];
if (error && errorCallback) {
errorCallback(new _Error(ErrorCode.SESSION_ERROR));
} else if (successCallback) {
successCallback();
}
this.#setReceiverVolumeLevelCallbacks.delete(volumeId);
break;
}
case "shim:/session/impl_stop": {
const { stopId, error } = message.data;
const [ successCallback, errorCallback ]
= this.#stopCallbacks.get(stopId) ?? [];
// Disconnect from extension messages
this.#listener.disconnect();
if (error && errorCallback) {
errorCallback(new _Error(ErrorCode.SESSION_ERROR));
} else {
this.status = SessionStatus.STOPPED;
for (const listener of this.#updateListeners) {
listener(false);
}
if (successCallback) {
successCallback();
}
}
this.#stopCallbacks.delete(stopId);
break;
}
}
})
public media: Media[]; public media: Media[];
public namespaces: Array<{ name: string }>; public namespaces: Array<{ name: string }>;
public senderApps: SenderApplication[]; public senderApps: SenderApplication[];
@@ -61,19 +214,9 @@ export default class Session {
, public displayName: string , public displayName: string
, public appImages: Image[] , public appImages: Image[]
, public receiver: Receiver , public receiver: Receiver
, _successCallback: (session: Session) => void) { , _successCallback: SessionSuccessCallback) {
_id.set(this, uuid());
_messageListeners.set(this, new Map());
_updateListeners.set(this, new Set());
_leaveCallbacks.set(this, new Map());
_sendMessageCallbacks.set(this, new Map());
_setReceiverMutedCallbacks.set(this, new Map());
_setReceiverVolumeLevelCallbacks.set(this, new Map());
_stopCallbacks.set(this, new Map());
this.#successCallback = _successCallback;
this.media = []; this.media = [];
this.namespaces = []; this.namespaces = [];
@@ -91,178 +234,9 @@ export default class Session {
, appId , appId
, sessionId , sessionId
} }
, _id: _id.get(this)! , _id: this.#id
}); });
} }
const listenerObject = onMessage(message => {
// Filter other session messages
if ((message as any)._id
&& (message as any)._id !== _id.get(this)) {
return;
}
switch (message.subject) {
case "shim:/session/stopped": {
// Disconnect from extension messages
_listener.get(this)?.disconnect();
this.status = SessionStatus.STOPPED;
const updateListeners = _updateListeners.get(this);
if (updateListeners) {
for (const listener of updateListeners) {
listener(false);
}
}
break;
}
case "shim:/session/connected": {
this.status = SessionStatus.CONNECTED;
this.sessionId = message.data.sessionId;
this.transportId = message.data.sessionId;
this.namespaces = message.data.namespaces;
this.displayName = message.data.displayName;
this.statusText = message.data.statusText;
if (_successCallback) {
_successCallback(this);
}
break;
}
case "shim:/session/updateStatus": {
const volume: Volume = message.data.volume;
if (volume) {
if (!this.receiver.volume) {
const receiverVolume = new Volume(
volume.level
, volume.muted);
receiverVolume.controlType = volume.controlType;
receiverVolume.stepInterval = volume.stepInterval;
this.receiver.volume = receiverVolume;
} else {
this.receiver.volume.level = volume.level;
this.receiver.volume.muted = volume.muted;
}
}
const updateListeners = _updateListeners.get(this);
if (updateListeners) {
for (const listener of updateListeners) {
listener(true);
}
}
break;
}
case "shim:/session/impl_addMessageListener": {
const { namespace, data } = message.data;
const messageListeners = _messageListeners
.get(this)?.get(namespace);
if (messageListeners) {
for (const listener of messageListeners) {
listener(namespace, data);
}
}
break;
}
case "shim:/session/impl_sendMessage": {
const { messageId, error } = message.data;
const [ successCallback, errorCallback ] =
_sendMessageCallbacks
.get(this)?.get(messageId) ?? [];
if (error && errorCallback) {
errorCallback(new _Error(ErrorCode.SESSION_ERROR));
} else if (successCallback) {
successCallback();
}
_sendMessageCallbacks.get(this)?.delete(messageId);
break;
}
case "shim:/session/impl_setReceiverMuted": {
const { volumeId, error } = message.data;
const [ successCallback, errorCallback ] =
_setReceiverMutedCallbacks
.get(this)?.get(volumeId) ?? [];
if (error && errorCallback) {
errorCallback(new _Error(ErrorCode.SESSION_ERROR));
} else if (successCallback) {
successCallback();
}
_setReceiverMutedCallbacks.get(this)?.delete(volumeId);
break;
}
case "shim:/session/impl_setReceiverVolumeLevel": {
const { volumeId, error } = message.data;
const [ successCallback, errorCallback ] =
_setReceiverVolumeLevelCallbacks
.get(this)?.get(volumeId) ?? [];
if (error && errorCallback) {
errorCallback(new _Error(ErrorCode.SESSION_ERROR));
} else if (successCallback) {
successCallback();
}
_setReceiverVolumeLevelCallbacks
.get(this)?.delete(volumeId);
break;
}
case "shim:/session/impl_stop": {
const { stopId, error } = message.data;
const [ successCallback, errorCallback ]
= _stopCallbacks.get(this)?.get(stopId) ?? [];
// Disconnect from extension messages
_listener.get(this)?.disconnect();
if (error && errorCallback) {
errorCallback(new _Error(ErrorCode.SESSION_ERROR));
} else {
this.status = SessionStatus.STOPPED;
const updateListeners = _updateListeners.get(this);
if (updateListeners) {
for (const listener of updateListeners) {
listener(false);
}
}
if (successCallback) {
successCallback();
}
}
_stopCallbacks.get(this)?.delete(stopId);
break;
}
}
});
_listener.set(this, listenerObject);
} }
@@ -274,21 +248,21 @@ export default class Session {
namespace: string namespace: string
, listener: MessageListener) { , listener: MessageListener) {
if (!_messageListeners.get(this)?.has(namespace)) { if (!this.#messageListeners.has(namespace)) {
_messageListeners.get(this)?.set(namespace, new Set()); this.#messageListeners.set(namespace, new Set());
} }
_messageListeners.get(this)?.get(namespace)?.add(listener); this.#messageListeners.get(namespace)?.add(listener);
sendMessageResponse({ sendMessageResponse({
subject: "bridge:/session/impl_addMessageListener" subject: "bridge:/session/impl_addMessageListener"
, data: { namespace } , data: { namespace }
, _id: _id.get(this)! , _id: this.#id
}); });
} }
public addUpdateListener (listener: UpdateListener) { public addUpdateListener (listener: UpdateListener) {
_updateListeners.get(this)?.add(listener); this.#updateListeners.add(listener);
} }
public leave ( public leave (
@@ -300,10 +274,10 @@ export default class Session {
sendMessageResponse({ sendMessageResponse({
subject: "bridge:/session/impl_leave" subject: "bridge:/session/impl_leave"
, data: { id } , data: { id }
, _id: _id.get(this)! , _id: this.#id
}); });
_leaveCallbacks.get(this)?.set(id, [ this.#leaveCallbacks.set(id, [
successCallback successCallback
, errorCallback , errorCallback
]); ]);
@@ -339,7 +313,7 @@ export default class Session {
const message = JSON.parse(data); const message = JSON.parse(data);
if (message.status && message.status.length > 0) { if (message.status && message.status.length > 0) {
const sessionId = _id.get(this); const sessionId = this.#id;
if (!sessionId) { if (!sessionId) {
return; return;
} }
@@ -383,14 +357,14 @@ export default class Session {
namespace: string namespace: string
, listener: MessageListener): void { , listener: MessageListener): void {
_messageListeners.get(this)?.get(namespace)?.delete(listener); this.#messageListeners.get(namespace)?.delete(listener);
} }
public removeUpdateListener ( public removeUpdateListener (
_namespace: string _namespace: string
, listener: UpdateListener): void { , listener: UpdateListener): void {
_updateListeners.get(this)?.delete(listener); this.#updateListeners.delete(listener);
} }
public sendMessage ( public sendMessage (
@@ -408,10 +382,10 @@ export default class Session {
, message , message
, messageId , messageId
} }
, _id: _id.get(this)! , _id: this.#id
}); });
_sendMessageCallbacks.get(this)?.set(messageId, [ this.#sendMessageCallbacks.set(messageId, [
successCallback successCallback
, errorCallback , errorCallback
]); ]);
@@ -427,10 +401,10 @@ export default class Session {
sendMessageResponse({ sendMessageResponse({
subject: "bridge:/session/impl_setReceiverMuted" subject: "bridge:/session/impl_setReceiverMuted"
, data: { muted, volumeId } , data: { muted, volumeId }
, _id: _id.get(this)! , _id: this.#id
}); });
_setReceiverMutedCallbacks.get(this)?.set(volumeId, [ this.#setReceiverMutedCallbacks.set(volumeId, [
successCallback successCallback
, errorCallback , errorCallback
]); ]);
@@ -446,10 +420,10 @@ export default class Session {
sendMessageResponse({ sendMessageResponse({
subject: "bridge:/session/impl_setReceiverVolumeLevel" subject: "bridge:/session/impl_setReceiverVolumeLevel"
, data: { newLevel, volumeId } , data: { newLevel, volumeId }
, _id: _id.get(this)! , _id: this.#id
}); });
_setReceiverVolumeLevelCallbacks.get(this)?.set(volumeId, [ this.#setReceiverVolumeLevelCallbacks.set(volumeId, [
successCallback successCallback
, errorCallback , errorCallback
]); ]);
@@ -464,10 +438,10 @@ export default class Session {
sendMessageResponse({ sendMessageResponse({
subject: "bridge:/session/impl_stop" subject: "bridge:/session/impl_stop"
, data: { stopId } , data: { stopId }
, _id: _id.get(this)! , _id: this.#id
}); });
_stopCallbacks.get(this)?.set(stopId, [ this.#stopCallbacks.set(stopId, [
successCallback successCallback
, errorCallback , errorCallback
]); ]);

View File

@@ -27,22 +27,19 @@ import { ErrorCode } from "../../enums";
import { onMessage, sendMessageResponse } from "../../../eventMessageChannel"; import { onMessage, sendMessageResponse } from "../../../eventMessageChannel";
import { CallbacksMap import { Callbacks
, ErrorCallback , ErrorCallback
, SuccessCallback , SuccessCallback
, UpdateListener } from "../../../types"; , UpdateListener } from "../../../types";
const _id = new WeakMap<Media, string>();
const _isActive = new WeakMap<Media, boolean>();
const _updateListeners = new WeakMap<Media, Set<UpdateListener>>();
const _sendMediaMessageCallbacks = new WeakMap<Media, CallbacksMap>();
const _lastCurrentTime = new WeakMap<Media, number>();
export default class Media { export default class Media {
#id = uuid();
#isActive = true;
#updateListeners = new Set<UpdateListener>();
#sendMediaMessageCallbacks = new Map<string, Callbacks>();
#lastCurrentTime?: number;
public activeTrackIds: (number[] | null) = null; public activeTrackIds: (number[] | null) = null;
public currentItemId: (number | null) = null; public currentItemId: (number | null) = null;
public customData: any = null; public customData: any = null;
@@ -64,13 +61,6 @@ export default class Media {
, public mediaSessionId: number , public mediaSessionId: number
, _internalSessionId: string) { , _internalSessionId: string) {
_id.set(this, uuid());
_isActive.set(this, true);
_updateListeners.set(this, new Set());
_sendMediaMessageCallbacks.set(this, new Map());
sendMessageResponse({ sendMessageResponse({
subject: "bridge:/media/initialize" subject: "bridge:/media/initialize"
, data: { , data: {
@@ -78,12 +68,11 @@ export default class Media {
, mediaSessionId , mediaSessionId
, _internalSessionId , _internalSessionId
} }
, _id: _id.get(this)! , _id: this.#id
}); });
onMessage(message => { onMessage(message => {
if ((message as any)._id if ((message as any)._id !== this.#id) {
&& (message as any)._id !== _id.get(this)) {
return; return;
} }
@@ -92,7 +81,7 @@ export default class Media {
const status = message.data; const status = message.data;
this.currentTime = status.currentTime; this.currentTime = status.currentTime;
_lastCurrentTime.set(this, status._lastCurrentTime); this.#lastCurrentTime = status._lastCurrentTime;
this.customData = status.customData; this.customData = status.customData;
this.playbackRate = status.playbackRate; this.playbackRate = status.playbackRate;
this.playerState = status.playerState; this.playerState = status.playerState;
@@ -112,11 +101,8 @@ export default class Media {
} }
// Call update listeners // Call update listeners
const updateListeners = _updateListeners.get(this); for (const listener of this.#updateListeners) {
if (updateListeners) { listener(true);
for (const listener of updateListeners) {
listener(true);
}
} }
break; break;
@@ -125,8 +111,8 @@ export default class Media {
case "shim:/media/sendMediaMessageResponse": { case "shim:/media/sendMediaMessageResponse": {
const { messageId, error } = message.data; const { messageId, error } = message.data;
const [ successCallback, errorCallback ] const [ successCallback, errorCallback ]
= _sendMediaMessageCallbacks = this.#sendMediaMessageCallbacks
.get(this)?.get(messageId) ?? []; .get(messageId) ?? [];
if (error && errorCallback) { if (error && errorCallback) {
errorCallback(new _Error(ErrorCode.SESSION_ERROR)); errorCallback(new _Error(ErrorCode.SESSION_ERROR));
@@ -142,7 +128,7 @@ export default class Media {
} }
public addUpdateListener (listener: UpdateListener): void { public addUpdateListener (listener: UpdateListener): void {
_updateListeners.get(this)?.add(listener); this.#updateListeners.add(listener);
} }
public editTracksInfo ( public editTracksInfo (
@@ -154,13 +140,12 @@ export default class Media {
} }
public getEstimatedTime (): number { public getEstimatedTime (): number {
const lastTime = _lastCurrentTime.get(this); if (this.currentTime === undefined
|| this.#lastCurrentTime === undefined) {
if (this.currentTime === undefined || lastTime === undefined) {
return 0; return 0;
} }
return this.currentTime + ((Date.now() / 1000) - lastTime); return this.currentTime + ((Date.now() / 1000) - this.#lastCurrentTime);
} }
public getStatus ( public getStatus (
@@ -260,7 +245,7 @@ export default class Media {
} }
public removeUpdateListener (listener: UpdateListener) { public removeUpdateListener (listener: UpdateListener) {
_updateListeners.get(this)?.delete(listener); this.#updateListeners.delete(listener);
} }
public seek ( public seek (
@@ -293,7 +278,7 @@ export default class Media {
this._sendMediaMessage( this._sendMediaMessage(
{ type: "STOP" } { type: "STOP" }
, () => { , () => {
_isActive.set(this, false); this.#isActive = false;
if (successCallback) { if (successCallback) {
successCallback(); successCallback();
} }
@@ -313,7 +298,7 @@ export default class Media {
, errorCallback?: ErrorCallback) { , errorCallback?: ErrorCallback) {
// TODO: Handle this and other errors better // TODO: Handle this and other errors better
if (!_isActive.get(this)) { if (!this.#isActive) {
if (errorCallback) { if (errorCallback) {
errorCallback(new _Error(ErrorCode.SESSION_ERROR errorCallback(new _Error(ErrorCode.SESSION_ERROR
, "INVALID_MEDIA_SESSION_ID" , "INVALID_MEDIA_SESSION_ID"
@@ -333,7 +318,7 @@ export default class Media {
const messageId = uuid(); const messageId = uuid();
_sendMediaMessageCallbacks.get(this)?.set(messageId, [ this.#sendMediaMessageCallbacks.set(messageId, [
successCallback successCallback
, errorCallback , errorCallback
]); ]);
@@ -344,7 +329,7 @@ export default class Media {
message message
, messageId , messageId
} }
, _id: _id.get(this)! , _id: this.#id
}); });
} }
} }