Clean up app message handling a little

This commit is contained in:
hensm
2022-04-25 10:17:59 +01:00
parent 88190bf12f
commit 418fc55112
11 changed files with 91 additions and 53 deletions

14
app/package-lock.json generated
View File

@@ -15,7 +15,6 @@
"mime-types": "^2.1.34", "mime-types": "^2.1.34",
"minimist": "^1.2.5", "minimist": "^1.2.5",
"node-fetch": "^3.2.2", "node-fetch": "^3.2.2",
"rage-edit": "*",
"tweetnacl": "^1.0.3", "tweetnacl": "^1.0.3",
"ws": "^8.5.0" "ws": "^8.5.0"
}, },
@@ -27,6 +26,7 @@
"fs-extra": "^10.0.1", "fs-extra": "^10.0.1",
"mustache": "^4.2.0", "mustache": "^4.2.0",
"pkg": "^5.5.2", "pkg": "^5.5.2",
"tiny-typed-emitter": "^2.1.0",
"typescript": "^4.6.2" "typescript": "^4.6.2"
}, },
"optionalDependencies": { "optionalDependencies": {
@@ -1888,6 +1888,12 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/tiny-typed-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz",
"integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==",
"dev": true
},
"node_modules/to-fast-properties": { "node_modules/to-fast-properties": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
@@ -3584,6 +3590,12 @@
} }
} }
}, },
"tiny-typed-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz",
"integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==",
"dev": true
},
"to-fast-properties": { "to-fast-properties": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",

View File

@@ -31,6 +31,7 @@
"fs-extra": "^10.0.1", "fs-extra": "^10.0.1",
"mustache": "^4.2.0", "mustache": "^4.2.0",
"pkg": "^5.5.2", "pkg": "^5.5.2",
"tiny-typed-emitter": "^2.1.0",
"typescript": "^4.6.2" "typescript": "^4.6.2"
}, },
"optionalDependencies": { "optionalDependencies": {

View File

@@ -2,9 +2,9 @@
import { Channel } from "castv2"; import { Channel } from "castv2";
import { sendMessage } from "../../lib/nativeMessaging"; import messaging from "../../messaging";
import { ReceiverDevice } from "../../types"; import { ReceiverDevice } from "../../messagingTypes";
import { ReceiverMessage } from "./types"; import { ReceiverMessage } from "./types";
import CastClient, { NS_CONNECTION, NS_HEARTBEAT } from "./client"; import CastClient, { NS_CONNECTION, NS_HEARTBEAT } from "./client";
@@ -74,7 +74,7 @@ export default class Session extends CastClient {
const { friendlyName } = this.receiverDevice; const { friendlyName } = this.receiverDevice;
sendMessage({ messaging.sendMessage({
subject: "cast:sessionCreated", subject: "cast:sessionCreated",
data: { data: {
sessionId: this.sessionId, sessionId: this.sessionId,
@@ -104,7 +104,7 @@ export default class Session extends CastClient {
break; break;
} }
sendMessage({ messaging.sendMessage({
subject: "cast:sessionUpdated", subject: "cast:sessionUpdated",
data: { data: {
sessionId: this.sessionId, sessionId: this.sessionId,
@@ -141,7 +141,7 @@ export default class Session extends CastClient {
messageData = JSON.stringify(messageData); messageData = JSON.stringify(messageData);
sendMessage({ messaging.sendMessage({
subject: "cast:receivedSessionMessage", subject: "cast:receivedSessionMessage",
data: { data: {
sessionId: this.sessionId, sessionId: this.sessionId,
@@ -187,7 +187,7 @@ export default class Session extends CastClient {
// Handle client connection closed // Handle client connection closed
this.client.on("close", () => { this.client.on("close", () => {
if (this.sessionId) { if (this.sessionId) {
sendMessage({ messaging.sendMessage({
subject: "cast:sessionStopped", subject: "cast:sessionStopped",
data: { sessionId: this.sessionId } data: { sessionId: this.sessionId }
}); });

View File

@@ -1,14 +1,10 @@
"use strict"; "use strict";
import castv2 from "castv2"; import messaging, { Message } from "../../messaging";
import { sendMessage } from "../../lib/nativeMessaging";
import { Message } from "../../messaging";
import Session from "./Session"; import Session from "./Session";
import CastClient, { NS_CONNECTION, NS_RECEIVER } from "./client"; import CastClient, { NS_CONNECTION, NS_RECEIVER } from "./client";
const sessions = new Map<string, Session>(); const sessions = new Map<string, Session>();
export function handleCastMessage(message: Message) { export function handleCastMessage(message: Message) {
@@ -29,7 +25,7 @@ export function handleCastMessage(message: Message) {
const session = sessions.get(sessionId); const session = sessions.get(sessionId);
if (!session) { if (!session) {
sendMessage({ messaging.sendMessage({
subject: "cast:impl_sendMessage", subject: "cast:impl_sendMessage",
data: { data: {
error: "Session does not exist", error: "Session does not exist",
@@ -44,7 +40,7 @@ export function handleCastMessage(message: Message) {
try { try {
session.sendReceiverMessage(messageData); session.sendReceiverMessage(messageData);
} catch (err) { } catch (err) {
sendMessage({ messaging.sendMessage({
subject: "cast:impl_sendMessage", subject: "cast:impl_sendMessage",
data: { data: {
error: `Failed to send message (${err})`, error: `Failed to send message (${err})`,
@@ -57,7 +53,7 @@ export function handleCastMessage(message: Message) {
} }
// Success // Success
sendMessage({ messaging.sendMessage({
subject: "cast:impl_sendMessage", subject: "cast:impl_sendMessage",
data: { sessionId, messageId } data: { sessionId, messageId }
}); });
@@ -70,7 +66,7 @@ export function handleCastMessage(message: Message) {
const session = sessions.get(sessionId); const session = sessions.get(sessionId);
if (!session) { if (!session) {
sendMessage({ messaging.sendMessage({
subject: "cast:impl_sendMessage", subject: "cast:impl_sendMessage",
data: { data: {
error: "Session does not exist", error: "Session does not exist",
@@ -91,7 +87,7 @@ export function handleCastMessage(message: Message) {
session.sendMessage(namespace, messageData); session.sendMessage(namespace, messageData);
} catch (err) { } catch (err) {
sendMessage({ messaging.sendMessage({
subject: "cast:impl_sendMessage", subject: "cast:impl_sendMessage",
data: { data: {
error: `Failed to send message (${err})`, error: `Failed to send message (${err})`,
@@ -104,7 +100,7 @@ export function handleCastMessage(message: Message) {
} }
// Success // Success
sendMessage({ messaging.sendMessage({
subject: "cast:impl_sendMessage", subject: "cast:impl_sendMessage",
data: { sessionId, messageId } data: { sessionId, messageId }
}); });
@@ -116,7 +112,7 @@ export function handleCastMessage(message: Message) {
const { receiverDevice } = message.data; const { receiverDevice } = message.data;
const client = new CastClient(); const client = new CastClient();
client.connect(receiverDevice.host). then(() => { client.connect(receiverDevice.host).then(() => {
(client.sendReceiverMessage as any)({ type: "STOP" }); (client.sendReceiverMessage as any)({ type: "STOP" });
}); });

View File

@@ -2,9 +2,10 @@
import mdns from "mdns"; import mdns from "mdns";
import messaging from "../messaging";
import { ReceiverDevice } from "../messagingTypes";
import Remote from "./cast/remote"; import Remote from "./cast/remote";
import { ReceiverDevice } from "../types";
import { sendMessage } from "../lib/nativeMessaging";
/** /**
* Chromecast TXT record * Chromecast TXT record
@@ -80,7 +81,7 @@ browser.on("serviceUp", service => {
port: service.port port: service.port
}; };
sendMessage({ messaging.sendMessage({
subject: "main:receiverDeviceUp", subject: "main:receiverDeviceUp",
data: { data: {
deviceId: device.id, deviceId: device.id,
@@ -94,7 +95,7 @@ browser.on("serviceUp", service => {
new Remote(device.host, { new Remote(device.host, {
// RECEIVER_STATUS // RECEIVER_STATUS
onReceiverStatusUpdate(status) { onReceiverStatusUpdate(status) {
sendMessage({ messaging.sendMessage({
subject: "main:receiverDeviceStatusUpdated", subject: "main:receiverDeviceStatusUpdated",
data: { deviceId: device.id, status } data: { deviceId: device.id, status }
}); });
@@ -103,7 +104,7 @@ browser.on("serviceUp", service => {
onMediaStatusUpdate(status) { onMediaStatusUpdate(status) {
if (!status) return; if (!status) return;
sendMessage({ messaging.sendMessage({
subject: "main:receiverDeviceMediaStatusUpdated", subject: "main:receiverDeviceMediaStatusUpdated",
data: { deviceId: device.id, status } data: { deviceId: device.id, status }
}); });
@@ -121,7 +122,7 @@ browser.on("serviceDown", service => {
// Filter invalid results // Filter invalid results
if (!service.name) return; if (!service.name) return;
sendMessage({ messaging.sendMessage({
subject: "main:receiverDeviceDown", subject: "main:receiverDeviceDown",
data: { deviceId: service.name } data: { deviceId: service.name }
}); });

View File

@@ -8,7 +8,7 @@ import stream from "stream";
import mime from "mime-types"; import mime from "mime-types";
import { sendMessage } from "../lib/nativeMessaging"; import messaging from "../messaging";
import { convertSrtToVtt } from "../lib/subtitles"; import { convertSrtToVtt } from "../lib/subtitles";
export let mediaServer: http.Server | undefined; export let mediaServer: http.Server | undefined;
@@ -30,7 +30,7 @@ export async function startMediaServer(filePath: string, port: number) {
fileName = path.basename(filePath); fileName = path.basename(filePath);
fileSize = stat.size; fileSize = stat.size;
} else { } else {
sendMessage({ messaging.sendMessage({
subject: "mediaCast:mediaServerError", subject: "mediaCast:mediaServerError",
data: "Media path is not a file." data: "Media path is not a file."
}); });
@@ -38,7 +38,7 @@ export async function startMediaServer(filePath: string, port: number) {
return; return;
} }
} catch (err) { } catch (err) {
sendMessage({ messaging.sendMessage({
subject: "mediaCast:mediaServerError", subject: "mediaCast:mediaServerError",
data: "Failed to find media path." data: "Failed to find media path."
}); });
@@ -48,7 +48,7 @@ export async function startMediaServer(filePath: string, port: number) {
const contentType = mime.lookup(filePath); const contentType = mime.lookup(filePath);
if (!contentType) { if (!contentType) {
sendMessage({ messaging.sendMessage({
subject: "mediaCast:mediaServerError", subject: "mediaCast:mediaServerError",
data: "Failed to find media type." data: "Failed to find media type."
}); });
@@ -137,12 +137,12 @@ export async function startMediaServer(filePath: string, port: number) {
}); });
mediaServer.on("close", () => { mediaServer.on("close", () => {
sendMessage({ messaging.sendMessage({
subject: "mediaCast:mediaServerStopped" subject: "mediaCast:mediaServerStopped"
}); });
}); });
mediaServer.on("error", err => { mediaServer.on("error", err => {
sendMessage({ messaging.sendMessage({
subject: "mediaCast:mediaServerError", subject: "mediaCast:mediaServerError",
data: err.message data: err.message
}); });
@@ -160,7 +160,7 @@ export async function startMediaServer(filePath: string, port: number) {
} }
if (!localAddresses.length) { if (!localAddresses.length) {
sendMessage({ messaging.sendMessage({
subject: "mediaCast:mediaServerError", subject: "mediaCast:mediaServerError",
data: "Failed to get local address." data: "Failed to get local address."
}); });
@@ -168,7 +168,7 @@ export async function startMediaServer(filePath: string, port: number) {
return; return;
} }
sendMessage({ messaging.sendMessage({
subject: "mediaCast:mediaServerStarted", subject: "mediaCast:mediaServerStarted",
data: { data: {
mediaPath: fileName, mediaPath: fileName,

View File

@@ -1,7 +1,6 @@
"use strict"; "use strict";
import { decodeTransform, encodeTransform } from "./lib/nativeMessaging"; import messaging, { Message } from "./messaging";
import { Message } from "./messaging";
import { handleCastMessage } from "./components/cast"; import { handleCastMessage } from "./components/cast";
import { startDiscovery, stopDiscovery } from "./components/discovery"; import { startDiscovery, stopDiscovery } from "./components/discovery";
@@ -21,11 +20,11 @@ process.on("SIGTERM", () => {
* Initializes the counterpart objects and is responsible * Initializes the counterpart objects and is responsible
* for managing existing ones. * for managing existing ones.
*/ */
decodeTransform.on("data", (message: Message) => { messaging.on("message", (message: Message) => {
switch (message.subject) { switch (message.subject) {
case "bridge:getInfo": case "bridge:getInfo":
case "bridge:/getInfo": { case "bridge:/getInfo": {
encodeTransform.write(__applicationVersion); messaging.send(__applicationVersion);
break; break;
} }

View File

@@ -1,14 +0,0 @@
"use strict";
import { DecodeTransform, EncodeTransform } from "../../transforms";
import { Message } from "../messaging";
export const decodeTransform = new DecodeTransform();
export const encodeTransform = new EncodeTransform();
process.stdin.pipe(decodeTransform);
encodeTransform.pipe(process.stdout);
export function sendMessage(message: Message) {
encodeTransform.write(message);
}

View File

@@ -1,5 +1,9 @@
"use strict"; "use strict";
import { TypedEmitter } from "tiny-typed-emitter";
import { DecodeTransform, EncodeTransform } from "../transforms";
import { import {
MediaStatus, MediaStatus,
ReceiverStatus, ReceiverStatus,
@@ -10,7 +14,7 @@ import {
ReceiverDevice, ReceiverDevice,
CastSessionCreatedDetails, CastSessionCreatedDetails,
CastSessionUpdatedDetails CastSessionUpdatedDetails
} from "./types"; } from "./messagingTypes";
/** /**
* IMPORTANT: * IMPORTANT:
@@ -193,3 +197,43 @@ type NarrowedMessage<L extends MessageBase<keyof MessageDefinitions>> =
: never; : never;
export type Message = NarrowedMessage<Messages[keyof Messages]>; export type Message = NarrowedMessage<Messages[keyof Messages]>;
interface MessengerEvents {
message: (message: Message) => void;
}
class Messenger extends TypedEmitter<MessengerEvents> {
// Native messaging transforms
private decodeTransform = new DecodeTransform();
private encodeTransform = new EncodeTransform();
constructor() {
super();
// Hook up stdin -> stdout
process.stdin.pipe(this.decodeTransform);
this.encodeTransform.pipe(process.stdout);
this.decodeTransform.on("error", err =>
console.error("err (message decode):", err)
);
this.encodeTransform.on("error", err =>
console.error("err (message encode):", err)
);
this.decodeTransform.on("data", (message: Message) => {
this.emit("message", message);
});
}
/** Sends a message to the extension. */
sendMessage(message: Message) {
this.encodeTransform.write(message);
}
send(data: any) {
this.encodeTransform.write(data);
}
}
export default new Messenger();

View File

@@ -3,7 +3,6 @@
import { spawn } from "child_process"; import { spawn } from "child_process";
import { Readable } from "stream"; import { Readable } from "stream";
import minimist from "minimist";
import WebSocket from "ws"; import WebSocket from "ws";
import { DecodeTransform, EncodeTransform } from "./transforms"; import { DecodeTransform, EncodeTransform } from "./transforms";