Reformat extension message definitions

This commit is contained in:
hensm
2021-04-24 02:37:51 +01:00
committed by Matt Hensman
parent 16c2c797d3
commit d806bfcf0c
10 changed files with 197 additions and 250 deletions

View File

@@ -88,10 +88,10 @@ export default class Media {
} }
private sendMessage (subject: string, data: any) { private sendMessage (subject: string, data: any) {
data._id = this.referenceId;
(sendMessage as any)({ (sendMessage as any)({
subject subject
, data , data
, _id: this.referenceId
}); });
} }
} }

View File

@@ -168,11 +168,11 @@ export default class Session {
} }
private sendMessage (subject: string, data: any = {}) { private sendMessage (subject: string, data: any = {}) {
data._id = this.referenceId;
sendMessage({ sendMessage({
// @ts-ignore // @ts-ignore
subject subject
, data , data
, _id: this.referenceId
}); });
} }

View File

@@ -12,12 +12,12 @@ const existingSessions: Map<string, Session> = new Map();
const existingMedia: Map<string, Media> = new Map(); const existingMedia: Map<string, Media> = new Map();
export function handleSessionMessage (message: any) { export function handleSessionMessage (message: any) {
if (!message._id) { if (!message.data._id) {
console.error("Session message missing _id"); console.error("Session message missing _id");
return; return;
} }
const sessionId = message._id; const sessionId = message.data._id;
if (existingSessions.has(sessionId)) { if (existingSessions.has(sessionId)) {
// Forward message to instance message handler // Forward message to instance message handler
@@ -35,12 +35,12 @@ export function handleSessionMessage (message: any) {
} }
export function handleMediaMessage (message: any) { export function handleMediaMessage (message: any) {
if (!message._id) { if (!message.data._id) {
console.error("Media message missing _id"); console.error("Media message missing _id");
return; return;
} }
const mediaId = message._id; const mediaId = message.data._id;
if (existingMedia.has(mediaId)) { if (existingMedia.has(mediaId)) {
// Forward message to instance message handler // Forward message to instance message handler

View File

@@ -11,7 +11,7 @@ interface TabConnectInfo {
frameId: number; frameId: number;
} }
export default class Messenger<T extends any[]> { export default class Messenger<T> {
connect (connectInfo: RuntimeConnectInfo) { connect (connectInfo: RuntimeConnectInfo) {
return browser.runtime.connect(connectInfo) as return browser.runtime.connect(connectInfo) as
unknown as TypedPort<T>; unknown as TypedPort<T>;

View File

@@ -1,11 +1,11 @@
"use strict"; "use strict";
const portMap = new WeakMap<any, browser.runtime.Port>(); const portMap = new WeakMap<TypedPort<any>, browser.runtime.Port>();
/** /**
* Allows typed access to a runtime.Port object. * Allows typed access to a runtime.Port object.
*/ */
export class TypedPort<T extends any[]> { export class TypedPort<T> {
public name: string; public name: string;
public error?: { message: string }; public error?: { message: string };
public sender?: browser.runtime.MessageSender; public sender?: browser.runtime.MessageSender;
@@ -36,18 +36,18 @@ export class TypedPort<T extends any[]> {
}; };
public onMessage = { public onMessage = {
addListener: (cb: (message: T[number]) => void) => { addListener: (cb: (message: T) => void) => {
portMap.get(this)?.onMessage.addListener(cb); portMap.get(this)?.onMessage.addListener(cb as any);
} }
, removeListener: (cb: (message: T[number]) => void) => { , removeListener: (cb: (message: T) => void) => {
portMap.get(this)?.onMessage.removeListener(cb); portMap.get(this)?.onMessage.removeListener(cb as any);
} }
, hasListener: (cb: (message: T[number]) => void) => { , hasListener: (cb: (message: T) => void) => {
return portMap.get(this)?.onMessage.hasListener(cb as any) ?? false; return portMap.get(this)?.onMessage.hasListener(cb as any) ?? false;
} }
}; };
public postMessage (message: T[number]) { public postMessage (message: T) {
portMap.get(this)?.postMessage(message); portMap.get(this)?.postMessage(message as any);
} }
} }

View File

@@ -5,7 +5,7 @@ import semver from "semver";
import { TypedPort } from "./TypedPort"; import { TypedPort } from "./TypedPort";
import logger from "./logger"; import logger from "./logger";
import { Messages, Message, Port } from "../messaging"; import { Message, Port } from "../messaging";
import nativeMessaging from "./nativeMessaging"; import nativeMessaging from "./nativeMessaging";
import options from "./options"; import options from "./options";

View File

@@ -6,262 +6,197 @@ import { TypedPort } from "./lib/TypedPort";
import { BridgeInfo } from "./lib/bridge"; import { BridgeInfo } from "./lib/bridge";
import { Receiver, ReceiverStatus } from "./types"; import { Receiver, ReceiverStatus } from "./types";
import { ReceiverSelectorMediaType } from "./background/receiverSelector"; import { ReceiverSelectorMediaType } from "./background/receiverSelector";
import { ReceiverSelection import { ReceiverSelection, ReceiverSelectionCast, ReceiverSelectionStop }
, ReceiverSelectionCast from "./background/receiverSelector/ReceiverSelector";
, ReceiverSelectionStop } from "./background/receiverSelector/ReceiverSelector";
import Volume from "./shim/cast/classes/Volume"; import Volume from "./shim/cast/classes/Volume";
import { MediaInfo } from "./shim/cast/media"; import { MediaInfo } from "./shim/cast/media";
// TODO: Document messages properly type MessagesBase = {
export type Messages = [ "popup:/sendRequestedAppId": {
{ requestedAppId?: string
subject: "popup:/sendRequestedAppId"
, data: {
requestedAppId?: string;
}
} }
, { , "popup:/populateReceiverList": {
subject: "popup:/populateReceiverList" receivers: Receiver[]
, data: { , defaultMediaType?: ReceiverSelectorMediaType
receivers: Receiver[] , availableMediaTypes?: ReceiverSelectorMediaType
, defaultMediaType?: ReceiverSelectorMediaType
, availableMediaTypes?: ReceiverSelectorMediaType
}
}
, {
subject: "popup:/close"
} }
, "popup:/close": {}
, { , "receiverSelector:/selected": ReceiverSelection
subject: "receiverSelector:/selected" , "receiverSelector:/stop": ReceiverSelection
, data: ReceiverSelection
} , "main:/shimInitialized": { appId: string }
, {
subject: "receiverSelector:/stop" , "main:/selectReceiverBegin": {}
, data: ReceiverSelection , "shim:/selectReceiverEnd": ReceiverSelectionCast
} , "shim:/selectReceiverStop": ReceiverSelectionStop
, { , "shim:/selectReceiverCancelled": {}
subject: "main:/shimInitialized"
, data: { appId: string; } , "main:/sessionCreated": {}
}
, { , "shim:/serviceUp": { id: Receiver["id"] }
subject: "main:/selectReceiverBegin" , "shim:/serviceDown": { id: Receiver["id"] }
}
, { , "shim:/initialized": BridgeInfo
subject: "shim:/selectReceiverEnd" , "shim:/launchApp": { receiver: Receiver }
, data: ReceiverSelectionCast
}
, {
subject: "shim:/selectReceiverStop"
, data: ReceiverSelectionStop
}
, {
subject: "shim:/selectReceiverCancelled"
}
, {
subject: "main:/sessionCreated"
}
, {
subject: "shim:/serviceUp"
, data: { id: Receiver["id"] }
}
, {
subject: "shim:/serviceDown"
, data: { id: Receiver["id"] }
}
, {
subject: "shim:/initialized"
, data: BridgeInfo
}
, {
subject: "shim:/launchApp"
, data: { receiver: Receiver }
}
// Session messages // Session messages
, { , "shim:/session/stopped": {}
subject: "shim:/session/stopped" , "shim:/session/connected": {
sessionId: string
, namespaces: Array<{ name: string }>
, displayName: string
, statusText: string
} }
, { , "shim:/session/updateStatus": { volume: Volume }
subject: "shim:/session/connected" , "shim:/session/impl_addMessageListener": {
, data: { namespace: string
sessionId: string; , data: string
namespaces: Array<{ name: string }>;
displayName: string;
statusText: string;
}
} }
, { , "shim:/session/impl_sendMessage": {
subject: "shim:/session/updateStatus" messageId: string
, data: { volume: Volume } , error: boolean
} }
, { , "shim:/session/impl_setReceiverMuted": {
subject: "shim:/session/impl_addMessageListener" volumeId: string
, data: { namespace: string, data: string } , error: boolean
} }
, { , "shim:/session/impl_setReceiverVolumeLevel": {
subject: "shim:/session/impl_sendMessage" volumeId: string
, data: { messageId: string, error: boolean } , error: boolean
} }
, { , "shim:/session/impl_stop": {
subject: "shim:/session/impl_setReceiverMuted" stopId: string
, data: { volumeId: string, error: boolean } , error: boolean
}
, {
subject: "shim:/session/impl_setReceiverVolumeLevel"
, data: { volumeId: string, error: boolean }
}
, {
subject: "shim:/session/impl_stop"
, data: { stopId: string, error: boolean }
} }
// Bridge session messages // Bridge session messages
, { , "bridge:/session/initialize": {
subject: "bridge:/session/initialize" address: string
, data: { , port: number
address: string , appId: string
, port: number , sessionId: string
, appId: string
, sessionId: string
}
, _id: string;
}
, {
subject: "bridge:/session/impl_leave"
, data: { id: string }
, _id: string , _id: string
} }
, { , "bridge:/session/impl_leave": {
subject: "bridge:/session/impl_sendMessage" id: string
, data: { namespace: string, message: any, messageId: string }
, _id: string , _id: string
} }
, { , "bridge:/session/impl_sendMessage": {
subject: "bridge:/session/impl_setReceiverMuted" namespace: string
, data: { muted: boolean, volumeId: string } , message: any
, messageId: string
, _id: string , _id: string
} }
, { , "bridge:/session/impl_setReceiverMuted": {
subject: "bridge:/session/impl_setReceiverVolumeLevel" muted: boolean
, data: { newLevel: number, volumeId: string } , volumeId: string
, _id: string , _id: string
} }
, { , "bridge:/session/impl_setReceiverVolumeLevel": {
subject: "bridge:/session/impl_stop" newLevel: number
, data: { stopId: string } , volumeId: string
, _id: string , _id: string
} }
, { , "bridge:/session/impl_stop": {
subject: "bridge:/session/impl_addMessageListener" stopId: string;
, data: { namespace: string } _id: string;
, _id: string }
, "bridge:/session/impl_addMessageListener": {
namespace: string;
_id: string;
} }
// Media messages // Media messages
, { , "shim:/media/update": {
subject: "shim:/media/update" currentTime: number
, data: { , _lastCurrentTime: number
currentTime: number , customData: any
, _lastCurrentTime: number , playbackRate: number
, customData: any , playerState: string
, playbackRate: number , repeatMode: string
, playerState: string , _volumeLevel: number
, repeatMode: string , _volumeMuted: boolean
, _volumeLevel: number , media: MediaInfo
, _volumeMuted: boolean , mediaSessionId: number
, media: MediaInfo
, mediaSessionId: number
}
} }
, { , "shim:/media/sendMediaMessageResponse": {
subject: "shim:/media/sendMediaMessageResponse" messageId: string
, data: { messageId: string, error: boolean } , error: boolean
} }
// Bridge media messages // Bridge media messages
, { , "bridge:/media/initialize": {
subject: "bridge:/media/initialize" sessionId: string
, data: { , mediaSessionId: number
sessionId: string , _internalSessionId: string
, mediaSessionId: number , _id: string
, _internalSessionId: string
}
, _id: string;
} }
, { , "bridge:/media/sendMediaMessage": {
subject: "bridge:/media/sendMediaMessage" message: any
, data: { message: any, messageId: string } , messageId: string
, _id: string; , _id: string
} }
// Bridge messages // Bridge messages
, { , "main:/receiverSelector/selected": ReceiverSelectionCast
subject: "main:/receiverSelector/selected" , "main:/receiverSelector/error": string
, data: ReceiverSelectionCast , "main:/receiverSelector/close": {}
} , "main:/receiverSelector/stop": ReceiverSelectionStop
, {
subject: "main:/receiverSelector/error"
, data: string
}
, {
subject: "main:/receiverSelector/close"
}
, {
subject: "main:/receiverSelector/stop"
, data: ReceiverSelectionStop
}
, {
subject: "bridge:/initialize"
, data: { shouldWatchStatus: boolean }
}
, {
subject: "bridge:/receiverSelector/open"
, data: any }
, {
subject: "bridge:/receiverSelector/close"
}
, {
subject: "bridge:/stopReceiverApp"
, data: { receiver: Receiver }
}
, {
subject: "bridge:/mediaServer/start"
, data: { filePath: string, port: number }
}
, { , "bridge:/initialize": { shouldWatchStatus: boolean }
subject: "mediaCast:/mediaServer/started"
, data: {
mediaPath: string
, subtitlePaths: string[]
, localAddress: string
}
}
, {
subject: "mediaCast:/mediaServer/stopped"
}
, {
subject: "mediaCast:/mediaServer/error"
}
, { , "bridge:/receiverSelector/open": any
subject: "main:/serviceUp" , "bridge:/receiverSelector/close": {}
, data: Receiver
}
, {
subject: "main:/serviceDown"
, data: { id: string }
}
, {
subject: "main:/receiverStatus"
, data: { id: string, status: ReceiverStatus }
}
];
export type Port = TypedPort<Messages>; , "bridge:/stopReceiverApp": { receiver: Receiver }
export type Message = Messages[number];
export default new Messenger<Messages>(); , "bridge:/mediaServer/start": {
filePath: string
, port: number
}
, "mediaCast:/mediaServer/started": {
mediaPath: string
, subtitlePaths: string[]
, localAddress: string
}
, "mediaCast:/mediaServer/stopped": {}
, "mediaCast:/mediaServer/error": {}
, "main:/serviceUp": Receiver
, "main:/serviceDown": { id: string }
, "main:/receiverStatus": {
id: string
, status: ReceiverStatus
}
}
interface MessageBase<K extends keyof MessagesBase> {
subject: K;
data: MessagesBase[K];
}
type Messages = {
[K in keyof MessagesBase]: MessageBase<K>;
}
/**
* For better call semantics, make message data key optional if
* specified as blank or with all-optional keys.
*/
type NarrowedMessage<L extends MessageBase<keyof MessagesBase>> =
L extends any
? {} extends L["data"]
? Omit<L, "data"> & Partial<L>
: L
: never;
export type Port = TypedPort<Message>;
export type Message = NarrowedMessage<Messages[keyof Messages]>;
export default new Messenger<Message>();

View File

@@ -50,7 +50,7 @@ export default class Session {
#listener = onMessage(message => { #listener = onMessage(message => {
// Filter other session messages // Filter other session messages
if ((message as any)._id !== this.#id) { if ((message as any).data._id !== this.#id) {
return; return;
} }
@@ -233,8 +233,8 @@ export default class Session {
, port: (receiver as any)._port , port: (receiver as any)._port
, appId , appId
, sessionId , sessionId
, _id: this.#id
} }
, _id: this.#id
}); });
} }
} }
@@ -256,8 +256,10 @@ export default class Session {
sendMessageResponse({ sendMessageResponse({
subject: "bridge:/session/impl_addMessageListener" subject: "bridge:/session/impl_addMessageListener"
, data: { namespace } , data: {
, _id: this.#id namespace
, _id: this.#id
}
}); });
} }
@@ -273,8 +275,10 @@ export default class Session {
sendMessageResponse({ sendMessageResponse({
subject: "bridge:/session/impl_leave" subject: "bridge:/session/impl_leave"
, data: { id } , data: {
, _id: this.#id id
, _id: this.#id
}
}); });
this.#leaveCallbacks.set(id, [ this.#leaveCallbacks.set(id, [
@@ -381,8 +385,8 @@ export default class Session {
namespace namespace
, message , message
, messageId , messageId
, _id: this.#id
} }
, _id: this.#id
}); });
this.#sendMessageCallbacks.set(messageId, [ this.#sendMessageCallbacks.set(messageId, [
@@ -400,8 +404,11 @@ export default class Session {
sendMessageResponse({ sendMessageResponse({
subject: "bridge:/session/impl_setReceiverMuted" subject: "bridge:/session/impl_setReceiverMuted"
, data: { muted, volumeId } , data: {
, _id: this.#id muted
, volumeId
, _id: this.#id
}
}); });
this.#setReceiverMutedCallbacks.set(volumeId, [ this.#setReceiverMutedCallbacks.set(volumeId, [
@@ -419,8 +426,11 @@ export default class Session {
sendMessageResponse({ sendMessageResponse({
subject: "bridge:/session/impl_setReceiverVolumeLevel" subject: "bridge:/session/impl_setReceiverVolumeLevel"
, data: { newLevel, volumeId } , data: {
, _id: this.#id newLevel
, volumeId
, _id: this.#id
}
}); });
this.#setReceiverVolumeLevelCallbacks.set(volumeId, [ this.#setReceiverVolumeLevelCallbacks.set(volumeId, [
@@ -437,8 +447,10 @@ export default class Session {
sendMessageResponse({ sendMessageResponse({
subject: "bridge:/session/impl_stop" subject: "bridge:/session/impl_stop"
, data: { stopId } , data: {
, _id: this.#id stopId
, _id: this.#id
}
}); });
this.#stopCallbacks.set(stopId, [ this.#stopCallbacks.set(stopId, [

View File

@@ -45,7 +45,7 @@ export default class Media {
#lastCurrentTime?: number; #lastCurrentTime?: number;
#listener = onMessage(message => { #listener = onMessage(message => {
if ((message as any)._id !== this.#id) { if ((message as any).data._id !== this.#id) {
return; return;
} }
@@ -130,8 +130,8 @@ export default class Media {
sessionId sessionId
, mediaSessionId , mediaSessionId
, _internalSessionId , _internalSessionId
, _id: this.#id
} }
, _id: this.#id
}); });
} }
@@ -348,8 +348,8 @@ export default class Media {
, data: { , data: {
message message
, messageId , messageId
, _id: this.#id
} }
, _id: this.#id
}); });
} }
} }

View File

@@ -75,7 +75,7 @@ class PopupApp extends Component<{}, PopupAppState> {
switch (message.subject) { switch (message.subject) {
case "popup:/sendRequestedAppId": { case "popup:/sendRequestedAppId": {
this.setState({ this.setState({
requestedAppId: message.data.requestedAppId requestedAppId: message.data?.requestedAppId
}); });
break; break;