Add strong typing to background messages

This commit is contained in:
Jakub Okoński 2019-10-26 21:55:15 +02:00
parent fbb3c9e50a
commit a8b740b1bd
10 changed files with 70 additions and 39 deletions

View file

@ -68,7 +68,7 @@ def get_block(lines):
"""next(lines) contains an open brace: return all the lines up to close brace.
Moves the lines iterator, so useful for consuming a block.
"""
brace_balance = 0
block = ""
@ -139,7 +139,7 @@ def background(lines, context):
return Messaging.message(
"excmd_background",
"{sig.name}",
[{message_params}],
{message_params}
)
}}\n""".format(**locals()))

View file

@ -2,7 +2,7 @@
/* tslint:disable:import-spacing */
import "@src/lib/browser_proxy_background"
import * as proxy_background from "@src/lib/browser_proxy_background"
import * as controller from "@src/lib/controller"
import * as perf from "@src/perf"
@ -55,8 +55,6 @@ controller.setExCmds({
"text": EditorCmds,
"hint": HintingCmds
})
messaging.addListener("excmd_background", messaging.attributeCaller(excmds_background))
messaging.addListener("controller_background", messaging.attributeCaller(controller))
// {{{ tri.contentLocation
// When loading the background, use the active tab to know what the current content url is
@ -165,10 +163,19 @@ browser.tabs.onCreated.addListener(
// An object to collect all of our statistics in one place.
const statsLogger: perf.StatsLogger = new perf.StatsLogger()
messaging.addListener(
"performance_background",
messaging.attributeCaller(statsLogger),
)
export const messages = {
excmd_background: excmds_background,
controller_background: controller,
performance_background: statsLogger,
download_background: {
downloadUrl: download_background.downloadUrl,
downloadUrlAs: download_background.downloadUrlAs,
},
browser_proxy_background: {shim: proxy_background.shim}
}
export type Messages = typeof messages
messaging.setupListener(messages)
// Listen for statistics from the background script and store
// them. Set this one up to log directly to the statsLogger instead of
// going through messaging.

View file

@ -146,14 +146,3 @@ export async function downloadUrlAs(url: string, saveAs: string) {
browser.downloads.onChanged.addListener(onDownloadComplete)
})
}
import * as Messaging from "@src/lib/messaging"
// Get messages from content
Messaging.addListener(
"download_background",
Messaging.attributeCaller({
downloadUrl,
downloadUrlAs,
}),
)

View file

@ -839,9 +839,9 @@ export async function restart() {
//#content
export async function saveas(...filename: string[]) {
if (filename.length > 0) {
return Messaging.message("download_background", "downloadUrlAs", [window.location.href, filename.join(" ")])
return Messaging.message("download_background", "downloadUrlAs", window.location.href, filename.join(" "))
} else {
return Messaging.message("download_background", "downloadUrl", [window.location.href, true])
return Messaging.message("download_background", "downloadUrl", window.location.href, true)
}
}
@ -3962,7 +3962,7 @@ export async function hint(option?: string, selectors?: string, ...rest: string[
selectHints = hinting.pipe_elements(
elems,
elem => {
Messaging.message("download_background", "downloadUrl", [new URL(elem[attr], window.location.href).href, saveAs])
Messaging.message("download_background", "downloadUrl", new URL(elem[attr], window.location.href).href, saveAs)
return elem
},
rapid,
@ -4074,7 +4074,7 @@ export function rot13(n: number) {
*/
//#content
export function run_exstr(...commands: string[]) {
return Messaging.message("controller_background", "acceptExCmd", commands)
return Messaging.message("controller_background", "acceptExCmd", commands.join(""))
}
// }}}

View file

@ -7,11 +7,11 @@ const browserProxy = new Proxy(Object.create(null), {
{
get(_, func) {
return (...args) =>
message("browser_proxy_background", "shim", [
message("browser_proxy_background", "shim",
api,
func,
args,
])
)
},
},
)

View file

@ -1,11 +1,5 @@
/** Shim to access BG browser APIs from content. */
function shim(api, func, args) {
export function shim(api, func, args) {
return browser[api][func](...args)
}
import { addListener, attributeCaller, MessageType } from "@src/lib/messaging"
addListener(
"browser_proxy_background" as MessageType,
attributeCaller({ shim }),
)

View file

@ -1,4 +1,5 @@
import { browserBg, activeTabId, ownTabId, getContext } from "@src/lib/webext"
import * as Messages from "@src/message_protocols"
import Logger from "@src/lib/logging"
const logger = new Logger("messaging")
@ -65,9 +66,48 @@ export function attributeCaller(obj) {
return handler
}
interface TypedMessage<Root, Type extends keyof Root, Command extends keyof Root[Type]> {
type: Type
command: Command
args: Parameters<Root[Type][Command]>
}
function backgroundHandler<
Root,
Type extends keyof Root,
Command extends keyof Root[Type]
>(root: Root,
message: TypedMessage<Root, Type, Command>,
sender: browser.runtime.MessageSender,
): ReturnType<Root[Type][Command]> {
return root[message.type][message.command](...message.args)
}
export function setupListener<Root>(root: Root) {
browser.runtime.onMessage.addListener((message: any, sender: browser.runtime.MessageSender) => {
if (message.type in root) {
if (!(message.command in root[message.type]))
throw new Error(`missing handler in protocol ${message.type} ${message.command}`)
if (!Array.isArray(message.args))
throw new Error(`wrong arguments in protocol ${message.type} ${message.command}`)
return backgroundHandler(root, message, sender)
}
});
}
/** Send a message to non-content scripts */
export async function message(type: NonTabMessageType, command, args?) {
return browser.runtime.sendMessage({ type, command, args } as Message)
export async function message<
Type extends keyof Messages.Background,
Command extends keyof Messages.Background[Type],
F extends ((...args: any) => any) & Messages.Background[Type][Command]
>(type: Type, command: Command, ...args: Parameters<F>) {
const message: TypedMessage<Messages.Background, Type, Command> = {
type,
command,
args
}
return browser.runtime.sendMessage<typeof message, ReturnType<F>>(message)
}
/** Message the active tab of the currentWindow */

3
src/message_protocols.ts Normal file
View file

@ -0,0 +1,3 @@
// This file re-exports types for message protocols for background, content and commandline contexts
export { Messages as Background } from "@src/background"

View file

@ -47,6 +47,6 @@ window.addEventListener("load", _ => {
// Periodically nag people about updates.
window.addEventListener("load", _ => {
if (config.get("update", "nag") === true) {
Messaging.message("controller_background", "acceptExCmd", ["updatecheck auto_polite"])
Messaging.message("controller_background", "acceptExCmd", "updatecheck auto_polite")
}
})

View file

@ -416,7 +416,5 @@ class MetricName {
}
function sendStats(list: PerformanceEntryList) {
messaging.message("performance_background", "receiveStatsJson", [
JSON.stringify(list),
])
messaging.message("performance_background", "receiveStatsJson", JSON.stringify(list))
}