Commit ac39b82b authored by Domi's avatar Domi

fix: offscreen service

parent 7f03fb1b
......@@ -5,7 +5,11 @@ import {
ContentScriptId,
} from "@/types"
import { waitMessage, tabUpdated, getLocal, getPipWindow } from "@/utils/ext"
import { setupOffscreenDocument, offscreenHtmlPath } from "./offscreen"
import {
createOffscreenDocument,
offscreenHtmlPath,
setupOffscreen,
} from "./offscreen"
import {
registerContentSidebar,
unregisterContentSidebar,
......@@ -14,7 +18,7 @@ import {
import config from "@/assets/config.json"
import { allFrameScript, contentMainScript } from "@/manifest"
import { getIsEdge } from "@/utils/ext"
import { contentInvoke } from "@/utils/invoke"
import { messageInvoke } from "@/utils/invoke"
type Config = typeof config
......@@ -81,10 +85,8 @@ async function updateWindow({ windowId, windowInfo }: UpdatePipWinOption) {
let currentSender: chrome.runtime.MessageSender | null = null
contentInvoke
.register(ServiceFunc.setupOffscreen, () =>
setupOffscreenDocument(offscreenHtmlPath)
)
messageInvoke
.register(ServiceFunc.setupOffscreen, () => setupOffscreen())
.register(ServiceFunc.getAllCommands, () => chrome.commands.getAll())
.register(ServiceFunc.createTab, (p: chrome.tabs.CreateProperties) =>
chrome.tabs.create(p)
......@@ -99,7 +101,7 @@ async function handleInvokeRequest(
sender: chrome.runtime.MessageSender
) {
currentSender = sender
let result = await contentInvoke.handleReqMsg(message)
let result = await messageInvoke.handleReqMsg(message)
if (!sender.tab?.id) {
console.error("sender tab id is undefined", sender)
......@@ -134,6 +136,9 @@ function handleMessage(message: any, sender: chrome.runtime.MessageSender) {
case MessageType.invokeRequest:
handleInvokeRequest(message, sender)
break
case MessageType.invokeResponse:
messageInvoke.handleResMsg(message)
break
case MessageType.contentMounted:
handleContentMounted(sender.tab!.id!)
break
......@@ -154,7 +159,7 @@ async function handleToggleMinimize() {
const tabId = pipWindow.tabId
contentInvoke.invoke({
messageInvoke.invoke({
tabId,
func: ServiceFunc.toggleMinimize,
args: [],
......
import { ServiceFunc } from "@/types"
import { messageInvoke } from "@/utils/invoke"
let creating: Promise<void> | null // A global promise to avoid concurrency issues
export async function setupOffscreenDocument(path: string) {
export async function createOffscreenDocument(path: string) {
// Check all windows controlled by the service worker to see if one
// of them is the offscreen document with the given path
const offscreenUrl = chrome.runtime.getURL(path)
......@@ -34,3 +37,12 @@ export async function setupOffscreenDocument(path: string) {
}
export const offscreenHtmlPath = "/offscreen.html"
export async function setupOffscreen() {
await createOffscreenDocument(offscreenHtmlPath)
await messageInvoke.invoke({
key: ServiceFunc.waitOffscreen,
func: ServiceFunc.waitOffscreen,
args: [],
})
}
......@@ -12,7 +12,7 @@ import { useI18n } from "@/utils/i18n"
import IconHide from "./icons/IconHide.vue"
import { pip } from "@/content/pip"
import { getPageIcon } from "@/utils/dom"
import { contentInvoke } from "@/utils/invoke"
import { messageInvoke } from "@/utils/invoke"
import IconKeyboard from "@/components/icons/IconKeyboard.vue"
import IconEdit from "@/components/icons/IconEdit.vue"
......@@ -68,7 +68,7 @@ watch(isMinimized, (value) => {
}
sheet.disabled = !value
contentInvoke.getAllCommands().then((commands) => {
messageInvoke.getAllCommands().then((commands) => {
const command = commands.find((c) => c.name == "toggleMinimize")
if (command) {
toggleMinimizeCommand.value = command
......@@ -83,7 +83,7 @@ onMounted(() => {
pipWindow.window?.addEventListener("resize", updateWindowInfo)
updateWindowInfo()
contentInvoke.register(ServiceFunc.toggleMinimize, () => {
messageInvoke.register(ServiceFunc.toggleMinimize, () => {
console.log("invoke toggleMinimize")
toggleMinimize()
})
......@@ -254,7 +254,7 @@ const handleEditCommand = (e: MouseEvent) => {
e.stopPropagation()
const desc = chrome.i18n.getMessage("toggle_minimize_desc")
const text = encodeURIComponent(desc)
contentInvoke.createTab({
messageInvoke.createTab({
url: `chrome://extensions/shortcuts#:~:text=${text}`,
})
}
......
<script setup lang="ts">
import { watch, computed, reactive, ref, onMounted, watchEffect } from "vue"
import { chatDocsPanel } from "@/store/content"
import { contentInvoke } from "@/utils/invoke"
import { messageInvoke } from "@/utils/invoke"
import { convertBlobToBase64, semanticClip } from "@/utils/utils"
import ScrollView from "@/components/ScrollView.vue"
import IconArrowBack from "@/components/icons/IconArrowBack.vue"
......@@ -126,8 +126,8 @@ watch(
if (maxInputType !== "token") return
if (!message) return
await contentInvoke.setupOffscreen()
const tokenLength = await contentInvoke.calcTokens(message)
await messageInvoke.setupOffscreen()
const tokenLength = await messageInvoke.calcTokens(message)
const rate = (message.length / tokenLength) * 0.95
const exceedMaxInput = tokenLength > maxInput
if (exceedMaxInput) {
......@@ -173,8 +173,8 @@ watch(
if (item.kind == "file" && typeof item.data != "string") {
const url = await convertBlobToBase64(item.data)
await contentInvoke.setupOffscreen()
const results = await contentInvoke.parseDoc({
await messageInvoke.setupOffscreen()
const results = await messageInvoke.parseDoc({
key: item.key,
type: item.type,
size: item.data.size,
......
......@@ -6,7 +6,7 @@ import IconArrowCircleRight from "@/components/icons/IconArrowCircleRight.vue"
import IconClose from "@/components/icons/IconClose.vue"
import { MessageType, ServiceFunc } from "@/types"
import { computed } from "vue"
import { contentInvoke } from "@/utils/invoke"
import { messageInvoke } from "@/utils/invoke"
import { handleImgError } from "@/utils/dom"
const globeImg = chrome.runtime.getURL("img/globe.svg")
......@@ -20,7 +20,7 @@ const isMinimized = computed(() => {
})
async function toggleMinimize() {
await contentInvoke.invoke({
await messageInvoke.invoke({
tabId: pipWindow.tabId,
func: ServiceFunc.toggleMinimize,
args: [],
......
......@@ -20,7 +20,7 @@ import {
addContentEventListener,
removeContentEventListener,
} from "@/content/event"
import { contentInvoke } from "@/utils/invoke"
import { messageInvoke } from "@/utils/invoke"
import { getPageIcon } from "@/utils/dom"
// import { PipEventName } from "@/types/pip"
......@@ -47,7 +47,7 @@ function handleMessage(
sendResponse({ type: MessageType.contentHere })
break
case MessageType.invokeResponse:
contentInvoke.handleResMsg(message)
messageInvoke.handleResMsg(message)
break
case MessageType.showChatDocs:
chatDocsPanel.visible = true
......@@ -58,7 +58,7 @@ function handleMessage(
sidebarAddon.url = message.url
break
case MessageType.invokeRequest:
contentInvoke.handleReqMsg(message).then((result) => {
messageInvoke.handleReqMsg(message).then((result) => {
if (result) {
chrome.runtime.sendMessage({
type: MessageType.invokeResponse,
......@@ -95,7 +95,7 @@ async function handlePipEvent(event: any) {
addContentEventListener(ContentEventType.pipLoaded, handlePipLoaded)
})
const window = await contentInvoke.invoke({
const window = await messageInvoke.invoke({
func: ServiceFunc.getPipWindow,
args: [
{
......@@ -105,7 +105,7 @@ async function handlePipEvent(event: any) {
],
})
const tab = await contentInvoke.invoke({
const tab = await messageInvoke.invoke({
func: ServiceFunc.getMyTab,
args: [],
})
......
......@@ -6,7 +6,7 @@ import TurndownService from "turndown"
import { MessageType, ServiceFunc, type ParseDocOptions } from "@/types"
import { Tiktoken } from "tiktoken/lite"
import cl100k_base from "tiktoken/encoders/cl100k_base.json"
import { contentInvoke } from "@/utils/invoke"
import { messageInvoke } from "@/utils/invoke"
pdfjs.GlobalWorkerOptions.workerSrc = "/js/pdf.worker.js"
......@@ -104,8 +104,11 @@ async function handleMessage(
) {
console.log("offscreen message: ", message, sender)
if (message?.type === MessageType.invokeRequest) {
const result = await contentInvoke.handleReqMsg(message)
if (result) {
const result = await messageInvoke.handleReqMsg(message)
if (!result) {
return
}
if (sender.tab?.id) {
chrome.runtime.sendMessage({
type: MessageType.forwardToTab,
tabId: sender.tab?.id,
......@@ -114,17 +117,30 @@ async function handleMessage(
...result,
},
})
} else {
chrome.runtime.sendMessage({
type: MessageType.invokeResponse,
...result,
})
}
}
}
contentInvoke
messageInvoke
.register(ServiceFunc.parseDoc, parseDoc)
.register(ServiceFunc.calcTokens, calcTokens)
.register(ServiceFunc.tokenSlice, tokenSlice)
.register(ServiceFunc.waitOffscreen, () => Promise.resolve())
chrome.runtime.onMessage.addListener(handleMessage)
chrome.runtime.sendMessage({
type: MessageType.invokeResponse,
key: ServiceFunc.waitOffscreen,
success: true,
value: null,
})
// for testing purposes
document.onclick = () => {
console.log("CLICK")
......
......@@ -4,7 +4,7 @@ import { createApp } from "vue"
import Popup from "./Popup.vue"
import { i18n } from "@/utils/i18n"
import { MessageType } from "@/types"
import { contentInvoke } from "@/utils/invoke"
import { messageInvoke } from "@/utils/invoke"
const app = createApp(Popup)
......@@ -14,7 +14,7 @@ app.mount("#app")
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
switch (message.type) {
case MessageType.invokeResponse:
contentInvoke.handleResMsg(message)
messageInvoke.handleResMsg(message)
break
}
})
......@@ -32,6 +32,7 @@ export enum ServiceFunc {
toggleMinimize = "toggle-minimize",
getPipWindow = "get-pip-window",
getMyTab = "get-my-tab",
waitOffscreen = "wait-offscreen",
}
export type ParseDocOptions = {
......
import { MessageType, ServiceFunc, type ParseDocOptions } from "@/types"
import Invoke, { type InvokeReq } from "./Invoke"
class ContentInvoke extends Invoke {
class MessageInvoke extends Invoke {
public async send(req: InvokeReq & { tabId?: number }) {
const key = this.key
const key = req.key || this.key
if (req.tabId) {
chrome.tabs.sendMessage(req.tabId, {
......@@ -74,6 +74,6 @@ class ContentInvoke extends Invoke {
}
}
const contentInvoke = new ContentInvoke("content")
const messageInvoke = new MessageInvoke("content")
export { ContentInvoke, contentInvoke }
export { MessageInvoke, messageInvoke }
export { Invoke } from "./Invoke"
export { ContentInvoke, contentInvoke } from "./ContentInvoke"
export { MessageInvoke, messageInvoke } from "./MessageInvoke"
export { WebviewInvoke } from "./WebviewInvoke"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment