Skip to content

Commit

Permalink
Merge pull request WorldBrain#837 from cdharris/feature/remote-functi…
Browse files Browse the repository at this point in the history
…on-refactor

Refactor remote function calls to implement typesafe interfaces
  • Loading branch information
blackforestboi authored Jul 16, 2019
2 parents 9516f31 + d82cd65 commit 68a97c6
Show file tree
Hide file tree
Showing 34 changed files with 615 additions and 132 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ stats.json
.sentryclirc
.DS_Store
local-backup
.idea
2 changes: 2 additions & 0 deletions src/activity-logger/background/log-page-visit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import { Tabs } from 'webextension-polyfill-ts'
import moment from 'moment'

import { TabManager } from './tab-manager'
// @ts-ignore
import analyzePage, { PageAnalyzer } from '../../page-analysis/background'
import * as searchIndex from '../../search'

import { FavIconChecker } from './types'

interface Props {
Expand Down
24 changes: 10 additions & 14 deletions src/activity-logger/background/tab-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import PausableTimer from '../../util/pausable-timer'
import { SIDEBAR_STORAGE_NAME } from '../../sidebar-overlay/constants'
import ScrollState from './scroll-state'
import { TabState, NavState } from './types'
import { remoteFunction } from '../../util/webextensionRPC'
import { remoteFunction, runInTab } from '../../util/webextensionRPC'
import { isLoggable } from '..'
import { TooltipInteractionInterface } from 'src/content-tooltip/types'
import { RibbonInteractionsInterface } from 'src/sidebar-overlay/ribbon/types'

export interface TabProps extends TabState {
storageAPI: Storage.Static
Expand Down Expand Up @@ -73,7 +75,6 @@ class Tab implements TabState {

return remoteFunction('toggleIFrameRender', {
tabId: this.id,
throwWhenNoResponse: false,
})(shouldRender)
}

Expand All @@ -82,32 +83,27 @@ class Tab implements TabState {
return
}

return remoteFunction('insertOrRemoveRibbon', {
tabId: this.id,
throwWhenNoResponse: false,
})()
return runInTab<RibbonInteractionsInterface>(
this.id,
).insertOrRemoveRibbon()
}

private async _toggleTooltip() {
if (!this.isLoaded || !this.isLoggable) {
return
}

return remoteFunction('insertOrRemoveTooltip', {
tabId: this.id,
throwWhenNoResponse: false,
})()
return runInTab<TooltipInteractionInterface>(
this.id,
).insertOrRemoveTooltip()
}

private async _updateRibbonState() {
if (!this.isLoaded || !this.isLoggable) {
return
}

return remoteFunction('updateRibbon', {
tabId: this.id,
throwWhenNoResponse: false,
})()
return runInTab<RibbonInteractionsInterface>(this.id).updateRibbon()
}

private _pauseLogTimer() {
Expand Down
19 changes: 15 additions & 4 deletions src/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import initStorex from './search/memex-storex'
import getDb, { setStorex } from './search/get-db'
import internalAnalytics from './analytics/internal'
import initSentry from './util/raven'
import {
makeRemotelyCallable,
setupRemoteFunctionsImplementations,
} from 'src/util/webextensionRPC'

// Features that require manual instantiation to setup
import DirectLinkingBackground from './direct-linking/background'
Expand All @@ -22,6 +26,7 @@ import TagsBackground from './tags/background'
import ActivityLoggerBackground from './activity-logger/background'
import SocialBackground from './social-integration/background'
import BookmarksBackground from './bookmarks/background'
import createNotification from 'src/util/notifications'

// Features that auto-setup
import './analytics/background'
Expand Down Expand Up @@ -75,10 +80,7 @@ export const tags = new TagsBackground({
})
tags.setupRemoteFunctions()

export const bookmarks = new BookmarksBackground({
storageManager,
})
bookmarks.setupRemoteFunctions()
export const bookmarks = new BookmarksBackground({ storageManager })

const backupModule = new backup.BackupBackgroundModule({
storageManager,
Expand Down Expand Up @@ -121,6 +123,15 @@ storageManager.finishInitialization().then(() => {
bgScript.setupAlarms(alarms)
})

// Gradually moving all remote function registrations here
setupRemoteFunctionsImplementations({
notifications: { createNotification },
bookmarks: {
addPageBookmark: search.remoteFunctions.addPageBookmark,
delPageBookmark: search.remoteFunctions.delPageBookmark,
},
})

// Attach interesting features onto global window scope for interested users
window['backup'] = backupModule
window['getDb'] = getDb
Expand Down
10 changes: 2 additions & 8 deletions src/bookmarks/background/index.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
import Storex from '@worldbrain/storex'

import BookmarksStorage from './storage'
import { makeRemotelyCallable } from 'src/util/webextensionRPC'
import normalizeUrl from 'src/util/encode-url-for-id'

export default class BookmarksBackground {
storage: BookmarksStorage

constructor({ storageManager }: { storageManager: Storex }) {
this.storage = new BookmarksStorage({ storageManager })
}

setupRemoteFunctions() {
makeRemotelyCallable({
addBookmark: this.addBookmark.bind(this),
delBookmark: this.delBookmark.bind(this),
})
this.addBookmark = this.addBookmark.bind(this)
this.delBookmark = this.delBookmark.bind(this)
}

async addBookmark({ url }: { url: string }) {
Expand Down
13 changes: 13 additions & 0 deletions src/bookmarks/background/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export interface BookmarksInterface {
addPageBookmark({
url,
timestamp,
tabId,
}: {
url: string
timestamp?: number
tabId?: number
}): Promise<any>

delPageBookmark({ url }: { url: string }): Promise<any>
}
5 changes: 2 additions & 3 deletions src/common-ui/containers/AddListDropdownContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
import { PageList } from '../../custom-lists/background/types'
import { ClickHandler } from '../../popup/types'
import { handleDBQuotaErrors } from 'src/util/error-handler'
import { notifications } from 'src/util/remote-functions-background'

export interface Props {
env?: 'inpage' | 'overview'
Expand Down Expand Up @@ -64,7 +65,6 @@ class AddListDropdownContainer extends Component<Props, State> {
private removeOpenTabsFromListRPC
private fetchListByIdRPC
private fetchListNameSuggestionsRPC
private createNotif
private inputEl: HTMLInputElement

constructor(props: Props) {
Expand All @@ -81,7 +81,6 @@ class AddListDropdownContainer extends Component<Props, State> {
this.fetchListNameSuggestionsRPC = remoteFunction(
'fetchListNameSuggestions',
)
this.createNotif = remoteFunction('createNotification')

this.fetchListSuggestions = debounce(300)(this.fetchListSuggestions)

Expand Down Expand Up @@ -110,7 +109,7 @@ class AddListDropdownContainer extends Component<Props, State> {
if (this.err && Date.now() - this.err.timestamp <= 1000) {
handleDBQuotaErrors(
err =>
this.createNotif({
notifications.createNotification({
requireInteraction: false,
title: 'Memex error: list adding',
message: err.message,
Expand Down
5 changes: 2 additions & 3 deletions src/common-ui/containers/IndexDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { ClickHandler } from '../../popup/types'
import { getLocalStorage, setLocalStorage } from 'src/util/storage'
import { TAG_SUGGESTIONS_KEY } from 'src/constants'
import { handleDBQuotaErrors } from 'src/util/error-handler'
import { notifications } from 'src/util/remote-functions-background'

export interface Props {
env?: 'inpage' | 'overview'
Expand Down Expand Up @@ -85,7 +86,6 @@ class IndexDropdownContainer extends Component<Props, State> {
private addTagsToOpenTabsRPC
private delTagsFromOpenTabsRPC
private processEvent
private createNotif
private inputEl: HTMLInputElement
private fetchUserSuggestionsRPC
private fetchHashtagSuggestionsRPC
Expand All @@ -99,7 +99,6 @@ class IndexDropdownContainer extends Component<Props, State> {
this.addTagsToOpenTabsRPC = remoteFunction('addTagsToOpenTabs')
this.delTagsFromOpenTabsRPC = remoteFunction('delTagsFromOpenTabs')
this.processEvent = remoteFunction('processEvent')
this.createNotif = remoteFunction('createNotification')
this.fetchUserSuggestionsRPC = remoteFunction('fetchUserSuggestions')
this.fetchHashtagSuggestionsRPC = remoteFunction(
'fetchHashtagSuggestions',
Expand Down Expand Up @@ -127,7 +126,7 @@ class IndexDropdownContainer extends Component<Props, State> {
if (this.err && Date.now() - this.err.timestamp <= 1000) {
handleDBQuotaErrors(
err =>
this.createNotif({
notifications.createNotification({
requireInteraction: false,
title: 'Memex error: tag adding',
message: err.message,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@ import {
createHighlight,
} from '../direct-linking/content_script/interactions'
import { setupUIContainer, destroyUIContainer } from './components'
import { remoteFunction, makeRemotelyCallable } from '../util/webextensionRPC'
import {
remoteFunction,
makeRemotelyCallable,
makeRemotelyCallableType,
} from '../util/webextensionRPC'
import { injectCSS } from '../search-injection/dom'
import { conditionallyShowHighlightNotification } from './onboarding-interactions'
import { TooltipInteractionInterface } from 'src/content-tooltip/types'

const openOptionsRPC = remoteFunction('openOptionsTab')
let mouseupListener = null
Expand Down Expand Up @@ -128,7 +133,7 @@ const insertOrRemoveTooltip = async ({ toolbarNotifications }) => {
* Sets up RPC functions to insert and remove Tooltip from Popup.
*/
export const setupRPC = ({ toolbarNotifications }) => {
makeRemotelyCallable({
makeRemotelyCallableType<TooltipInteractionInterface>({
showContentTooltip: async () => {
if (!showTooltip) {
await insertTooltip({ toolbarNotifications })
Expand All @@ -138,11 +143,11 @@ export const setupRPC = ({ toolbarNotifications }) => {
showTooltip(position)
}
},
insertTooltip: ({ override } = {}) => {
insertTooltip: ({ override }) => {
manualOverride = !!override
insertTooltip({ toolbarNotifications })
},
removeTooltip: ({ override } = {}) => {
removeTooltip: ({ override }) => {
manualOverride = !!override
removeTooltip()
},
Expand Down Expand Up @@ -225,9 +230,9 @@ export function userSelectedText() {
const container = selection.getRangeAt(0).commonAncestorContainer
const extras = isAnchorOrContentEditable(container)

const userSelectedText =
const userSelectedTextString =
!!selection && !selection.isCollapsed && !!selectedString && !extras
return userSelectedText
return userSelectedTextString
}

function isTargetInsideTooltip(event) {
Expand Down
7 changes: 7 additions & 0 deletions src/content-tooltip/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,10 @@ export interface KeyboardShortcuts {
addTag: Shortcut
link: Shortcut
}

export interface TooltipInteractionInterface {
showContentTooltip: () => Promise<any>
insertTooltip: ({ override }?: { override?: boolean }) => any
removeTooltip: ({ override }?: { override?: boolean }) => any
insertOrRemoveTooltip: () => Promise<any>
}
13 changes: 10 additions & 3 deletions src/direct-linking/background/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import Storex from '@worldbrain/storex'
import { browser, Tabs } from 'webextension-polyfill-ts'

import { makeRemotelyCallable, remoteFunction } from 'src/util/webextensionRPC'
import {
makeRemotelyCallable,
remoteFunction,
runInTab,
} from 'src/util/webextensionRPC'
import DirectLinkingBackend from './backend'
import { setupRequestInterceptor } from './redirect'
import { AnnotationRequests } from './request'
Expand All @@ -13,6 +17,7 @@ import { OpenSidebarArgs } from 'src/sidebar-overlay/types'
import { Annotation, KeyboardActions } from 'src/sidebar-overlay/sidebar/types'
import SocialBG from 'src/social-integration/background'
import { buildPostUrlId } from 'src/social-integration/util'
import { RibbonInteractionsInterface } from 'src/sidebar-overlay/ribbon/types'

interface TabArg {
tab: Tabs.Tab
Expand Down Expand Up @@ -108,7 +113,9 @@ export default class DirectLinkingBackground {
if (tabId === activeTab.id && changeInfo.status === 'complete') {
// Necessary to insert the ribbon/sidebar in case the user has turned
// it off.
await remoteFunction('insertRibbon', { tabId })()
await runInTab<RibbonInteractionsInterface>(
tabId,
).insertRibbon()
await remoteFunction('goToAnnotation', { tabId })(annotation)
browser.tabs.onUpdated.removeListener(listener)
}
Expand Down Expand Up @@ -154,7 +161,7 @@ export default class DirectLinkingBackground {

// Make sure that the ribbon is inserted before trying to open the
// sidebar.
await remoteFunction('insertRibbon', { tabId })({
await runInTab<RibbonInteractionsInterface>(tabId).insertRibbon({
override,
forceExpandRibbon,
openToCollections,
Expand Down
2 changes: 1 addition & 1 deletion src/imports/background/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NotifOpts } from '../../util/notifications'
import { NotifOpts } from '../../util/notification-types'

export const REMINDER_NOTIF: Partial<NotifOpts> = {
title: 'Memex Importer',
Expand Down
4 changes: 2 additions & 2 deletions src/options/blacklist/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import * as selectors from './selectors'
import { STORAGE_KEY } from './constants'
import { EVENT_NAMES } from '../../analytics/internal/constants'
import { handleDBQuotaErrors } from 'src/util/error-handler'
import { notifications } from 'src/util/remote-functions-background'

const deletePagesByPattern = remoteFunction('delPagesByPattern')
const getMatchingPageCount = remoteFunction('getMatchingPageCount')
const createNotifRPC = remoteFunction('createNotification')
const dirtyEstsCache = remoteFunction('dirtyEstsCache')
const processEvent = remoteFunction('processEvent')

Expand Down Expand Up @@ -126,7 +126,7 @@ export const removeMatchingDocs = expression => async (dispatch, getState) => {
} catch (err) {
handleDBQuotaErrors(
error =>
createNotifRPC({
notifications.createNotification({
requireInteraction: false,
title: 'Memex error: deleting page',
message: error.message,
Expand Down
4 changes: 2 additions & 2 deletions src/overview/delete-confirm-modal/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { acts as resultsActs, selectors as results } from '../results'
import { actions as searchFilterActs } from '../../search-filters'
import { EVENT_NAMES } from '../../analytics/internal/constants'
import { handleDBQuotaErrors } from 'src/util/error-handler'
import { notifications } from 'src/util/remote-functions-background'

export const show = createAction<{ url: string; index: number }>(
'deleteConf/show',
Expand All @@ -19,7 +20,6 @@ export const resetDeleteIndex = createAction('deleteConf/resetDeleteIndex')

const processEventRPC = remoteFunction('processEvent')
const deletePagesRPC = remoteFunction('delPages')
const createNotifRPC = remoteFunction('createNotification')
const deleteSocialPagesRPC = remoteFunction('delSocialPages')

export const deleteDocs: () => Thunk = () => async (dispatch, getState) => {
Expand Down Expand Up @@ -47,7 +47,7 @@ export const deleteDocs: () => Thunk = () => async (dispatch, getState) => {
} catch (err) {
handleDBQuotaErrors(
error =>
this.createNotif({
notifications.createNotification({
requireInteraction: false,
title: 'Memex error: deleting page',
message: error.message,
Expand Down
Loading

0 comments on commit 68a97c6

Please sign in to comment.