Skip to content

Commit

Permalink
Add PortMessanger interface
Browse files Browse the repository at this point in the history
  • Loading branch information
thetarnav committed Dec 17, 2024
1 parent 4effefa commit e266334
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 51 deletions.
22 changes: 11 additions & 11 deletions packages/extension/background/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ chrome.runtime.onConnect.addListener(async port => {
let data: TabData

const config: TabDataConfig = {
toContent: content_messanger.postPortMessage,
fromContent: content_messanger.onPortMessage,
toContent: content_messanger.post,
fromContent: content_messanger.on,
forwardToDevtools: fn => (forwardHandler = fn),
forwardToClient: message => port.postMessage(message),
}
Expand All @@ -181,15 +181,15 @@ chrome.runtime.onConnect.addListener(async port => {
tab_data_map.set(tab_id, data)

// "Versions" from content-script
bridge.once(content_messanger.onPortMessage, 'Versions', v => {
bridge.once(content_messanger.on, 'Versions', v => {
data.setVersions(v)

// Change the popup icon to indicate that Solid is present on the page
chrome.action.setIcon({tabId: tab_id, path: icons.blue})
})

// "DetectSolid" from content-script (realWorld)
content_messanger.onPortMessage('Detected', state => data.set_detected(state))
content_messanger.on('Detected', state => data.set_detected(state))

port.onDisconnect.addListener(() => {
data.disconnected()
Expand Down Expand Up @@ -220,7 +220,7 @@ chrome.runtime.onConnect.addListener(async port => {
const content_messanger = await data.untilContentScriptConnect()

// "Versions" means the devtools client is present
data.onVersions(v => devtools_messanger.postPortMessage('Versions', v))
data.onVersions(v => devtools_messanger.post('Versions', v))

port.onDisconnect.addListener(() => {
content_messanger.post('DevtoolsClosed')
Expand All @@ -244,16 +244,16 @@ chrome.runtime.onConnect.addListener(async port => {
const content_messanger = await data.untilContentScriptConnect()

data.onVersions(v => {
panel_messanger.postPortMessage('Versions', v)
panel_messanger.post('Versions', v)
// notify the content script that the devtools panel is ready
content_messanger.post('DevtoolsOpened')
})

content_messanger.on('ResetPanel', () => {
panel_messanger.postPortMessage('ResetPanel')
panel_messanger.post('ResetPanel')
})
data.onContentScriptDisconnect(() => {
panel_messanger.postPortMessage('ResetPanel')
panel_messanger.post('ResetPanel')
})

if (!data.config) {
Expand All @@ -273,7 +273,7 @@ chrome.runtime.onConnect.addListener(async port => {
}

// Forward messages from Panel to Content Script (client)
panel_messanger.onForwardMessage(message => {
panel_messanger.onForward(message => {
if (!data.config) {
error(`Cannot forward message, no ${bridge.Place_Name.Content_Script} connection.`, message)
} else {
Expand All @@ -296,10 +296,10 @@ chrome.runtime.onConnect.addListener(async port => {
port)

data.onVersions(v => {
popup_messanger.postPortMessage('Versions', v)
popup_messanger.post('Versions', v)
})
data.onDetected(state => {
popup_messanger.postPortMessage('Detected', state)
popup_messanger.post('Detected', state)
})

break
Expand Down
13 changes: 6 additions & 7 deletions packages/extension/content/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ let devtools_opened = false
const fromClient = bridge.makeMessageListener(bridge.Place_Name.Content_Script)
const toClient = bridge.makePostMessage()

const {postPortMessage: toBackground, onPortMessage: fromBackground} =
bridge.createPortMessanger(
const bg_messanger = bridge.createPortMessanger(
bridge.Place_Name.Content_Script,
bridge.Place_Name.Background,
port)
Expand Down Expand Up @@ -74,7 +73,7 @@ window.addEventListener('message', e => {

const state = e.data.state as bridge.DetectionState

toBackground('Detected', state)
bg_messanger.post('Detected', state)

/* Load Debugger_Real_World */
if (state.Debugger && !debugger_real_world_added) {
Expand All @@ -94,26 +93,26 @@ fromClient('Debugger_Connected', versions => {
'color: #e38b1b',
)

toBackground('Versions', {
bg_messanger.post('Versions', {
client: versions.client,
solid: versions.solid,
extension: extension_version,
expectedClient: import.meta.env.EXPECTED_CLIENT,
})

fromClient('ResetPanel', () => toBackground('ResetPanel'))
fromClient('ResetPanel', () => bg_messanger.post('ResetPanel'))

if (devtools_opened) toClient('DevtoolsOpened')
})

// After page reload, the content script is reloaded but the background script is not.
// This means that 'DevtoolsOpened' message will come after the Client is setup.
// We need to send it after it connects.
fromBackground('DevtoolsOpened', () => {
bg_messanger.on('DevtoolsOpened', () => {
devtools_opened = true
toClient('DevtoolsOpened')
})
fromBackground('DevtoolsClosed', () => toClient('DevtoolsClosed'))
bg_messanger.on('DevtoolsClosed', () => toClient('DevtoolsClosed'))

fromClient(e => {
// forward all client messages to the background script in
Expand Down
4 changes: 2 additions & 2 deletions packages/extension/devtools/devtools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ log(bridge.Place_Name.Devtools_Script+' loaded.')
// Create a connection to the background page
const port = chrome.runtime.connect({name: bridge.ConnectionName.Devtools})

const {onPortMessage: fromBackground} = bridge.createPortMessanger(
const bg_messanger = bridge.createPortMessanger(
bridge.Place_Name.Devtools_Script,
bridge.Place_Name.Background,
port)
Expand All @@ -25,7 +25,7 @@ const {onPortMessage: fromBackground} = bridge.createPortMessanger(
const PATH_PREFIX = import.meta.env.BROWSER === 'firefox' ? '/' : ''

// "Versions" mean that devtools client is on the page
bridge.once(fromBackground, 'Versions', () => {
bridge.once(bg_messanger.on, 'Versions', () => {

log('Debugger connected -> Creating Devtools_Panel...')

Expand Down
16 changes: 8 additions & 8 deletions packages/extension/panel/panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import '@solid-devtools/frontend/dist/styles.css'
log(bridge.Place_Name.Panel+' loaded.')

const port = chrome.runtime.connect({name: bridge.ConnectionName.Panel})
const {postPortMessage: toBackground, onPortMessage: fromBackground} =
bridge.createPortMessanger<Debugger.OutputChannels, Debugger.InputChannels>(
bridge.Place_Name.Panel,
bridge.Place_Name.Background,
port)
const bg_messanger = bridge.createPortMessanger
<Debugger.OutputChannels, Debugger.InputChannels>(
bridge.Place_Name.Panel,
bridge.Place_Name.Background,
port)

function App() {
const [versions, setVersions] = createSignal<bridge.Versions>({
Expand All @@ -28,13 +28,13 @@ function App() {
extension: '',
})

bridge.once(fromBackground, 'Versions', setVersions)
bridge.once(bg_messanger.on, 'Versions', setVersions)

const devtools = createDevtools()

devtools.bridge.output.listen(e => toBackground(e.name, e.details))
devtools.bridge.output.listen(e => bg_messanger.post(e.name, e.details))

fromBackground(e => {
bg_messanger.on(e => {
// some events are internal and should not be forwarded to the devtools
if (!(e.name in devtools.bridge.input)) return
devtools.bridge.input.emit(e.name as any, e.details)
Expand Down
6 changes: 3 additions & 3 deletions packages/extension/popup/popup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ log(bridge.Place_Name.Popup+' loaded.')

// Create a connection to the background page
const port = chrome.runtime.connect({name: bridge.ConnectionName.Popup})
const {onPortMessage: fromBackground} = bridge.createPortMessanger(
const bg_messanger = bridge.createPortMessanger(
bridge.Place_Name.Popup,
bridge.Place_Name.Background,
port)
Expand All @@ -23,8 +23,8 @@ const [detectionState, setDetectionState] = s.createSignal<bridge.DetectionState
Debugger: false,
})

fromBackground('Detected', setDetectionState)
bridge.once(fromBackground, 'Versions', setVersions)
bg_messanger.on('Detected', setDetectionState)
bg_messanger.on('Versions', setVersions)

const App: s.Component = () => {
return <>
Expand Down
48 changes: 28 additions & 20 deletions packages/extension/shared/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ File for utilities, constants and types related to the communication between the
*/

import {log, log_message} from '@solid-devtools/shared/utils'
import {error, log, log_message} from '@solid-devtools/shared/utils'

export const DEVTOOLS_ID_PREFIX = '[solid-devtools]_'

Expand Down Expand Up @@ -39,31 +39,35 @@ export type DetectEvent = {
const LOG_MESSAGES = import.meta.env.DEV
// const LOG_MESSAGES: boolean = true

export interface PortMessanger<
IM extends {[K in string]: any},
OM extends {[K in string]: any},
> {
post: PostMessageFn<OM>
on: OnMessageFn<IM>
onForward: (handler: (event: ForwardPayload) => void) => void
}

export function createPortMessanger<
IM extends {[K in string]: any},
OM extends {[K in string]: any},
>(
place_name_here: string,
place_name_conn: string,
port: chrome.runtime.Port,
): {
postPortMessage: PostMessageFn<OM>
onPortMessage: OnMessageFn<IM>
onForwardMessage: (handler: (event: ForwardPayload) => void) => void
} {
_port: chrome.runtime.Port,
): PortMessanger<IM, OM> {
let port: chrome.runtime.Port | null = _port

let forwardHandler: ((event: ForwardPayload) => void) | undefined
let listeners: {[K in any]?: ((event: any) => void)[]} = {}

let port_name = port.name.replace(DEVTOOLS_ID_PREFIX, '')

let connected = true
if (LOG_MESSAGES) log(`${port_name} port connected.`)
if (LOG_MESSAGES) log(`${place_name_here}-${place_name_conn} port connected.`)

port.onDisconnect.addListener(() => {
if (LOG_MESSAGES) log(`${port_name} port disconnected.`)
connected = false
if (LOG_MESSAGES) log(`${place_name_here}-${place_name_conn} port disconnected.`)
listeners = {}
port.onMessage.removeListener(onMessage)
_port.onMessage.removeListener(onMessage)
port = null
})

function onMessage(e: any) {
Expand Down Expand Up @@ -92,16 +96,20 @@ export function createPortMessanger<
port.onMessage.addListener(onMessage)

return {
postPortMessage: (name, details?: any) => {
if (!connected) return
port.postMessage({name, details})
post: (name, details?: any) => {
if (!port) {
error(`Trying to post ${String(name)} message to disconnected port ${place_name_here}-${place_name_conn}`)
} else {
port.postMessage({name, details})
}
},
onPortMessage: (...args: [any, any] | [any]) => {
on: (...args: [any, any] | [any]) => {

let name = typeof args[0] === 'string' ? args[0] : '*'
let handler = typeof args[0] === 'string' ? args[1] : args[0]

if (!connected) {
if (!port) {
error(`Trying to listen to disconnected port ${place_name_here}-${place_name_conn}`)
return () => {/**/}
}

Expand All @@ -110,7 +118,7 @@ export function createPortMessanger<

return () => (listeners[name] = arr.filter(l => l !== handler) as any)
},
onForwardMessage(handler) {
onForward(handler) {
forwardHandler = handler
},
}
Expand Down

0 comments on commit e266334

Please sign in to comment.