Skip to content

Commit

Permalink
refactor: switch Awilix container injection mode to proxy (#498)
Browse files Browse the repository at this point in the history
* Change Awilix container injection mode

* use Cradle for types; don't import each service type

Co-authored-by: Radu-Cristian Popa <[email protected]>

* lint fix

---------

Co-authored-by: Sid Vishnoi <[email protected]>
  • Loading branch information
raducristianpopa and sidvishnoi authored Aug 16, 2024
1 parent 708838e commit 40b21c2
Show file tree
Hide file tree
Showing 15 changed files with 187 additions and 118 deletions.
4 changes: 2 additions & 2 deletions src/background/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { createLogger, Logger } from '@/shared/logger'
import { LOG_LEVEL } from '@/shared/defines'
import { tFactory, type Translation } from '@/shared/helpers'

interface Cradle {
export interface Cradle {
logger: Logger
browser: Browser
events: EventsService
Expand All @@ -34,7 +34,7 @@ interface Cradle {

export const configureContainer = () => {
const container = createContainer<Cradle>({
injectionMode: InjectionMode.CLASSIC
injectionMode: InjectionMode.PROXY
})

const logger = createLogger(LOG_LEVEL)
Expand Down
57 changes: 35 additions & 22 deletions src/background/services/background.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
import { type Browser } from 'webextension-polyfill'
import type { Browser } from 'webextension-polyfill'
import {
type ToBackgroundMessage,
PopupToBackgroundAction,
ContentToBackgroundAction
} from '@/shared/messages'
import type {
EventsService,
MonetizationService,
OpenPaymentsService,
TabEvents,
SendToPopup,
StorageService,
Heartbeat
} from '.'
import { Logger } from '@/shared/logger'
import {
failure,
getNextOccurrence,
Expand All @@ -23,22 +13,45 @@ import {
import { OpenPaymentsClientError } from '@interledger/open-payments/dist/client/error'
import { getCurrentActiveTab, OPEN_PAYMENTS_ERRORS } from '@/background/utils'
import { PERMISSION_HOSTS } from '@/shared/defines'
import type { Cradle } from '@/background/container'

type AlarmCallback = Parameters<Browser['alarms']['onAlarm']['addListener']>[0]
const ALARM_RESET_OUT_OF_FUNDS = 'reset-out-of-funds'

export class Background {
constructor(
private browser: Browser,
private openPaymentsService: OpenPaymentsService,
private monetizationService: MonetizationService,
private storage: StorageService,
private logger: Logger,
private tabEvents: TabEvents,
private sendToPopup: SendToPopup,
private events: EventsService,
private heartbeat: Heartbeat
) {}
private browser: Cradle['browser']
private openPaymentsService: Cradle['openPaymentsService']
private monetizationService: Cradle['monetizationService']
private storage: Cradle['storage']
private logger: Cradle['logger']
private tabEvents: Cradle['tabEvents']
private sendToPopup: Cradle['sendToPopup']
private events: Cradle['events']
private heartbeat: Cradle['heartbeat']

constructor({
browser,
openPaymentsService,
monetizationService,
storage,
logger,
tabEvents,
sendToPopup,
events,
heartbeat
}: Cradle) {
Object.assign(this, {
browser,
openPaymentsService,
monetizationService,
storage,
sendToPopup,
tabEvents,
logger,
events,
heartbeat
})
}

async start() {
this.bindOnInstalled()
Expand Down
8 changes: 6 additions & 2 deletions src/background/services/deduplicator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Logger } from '@/shared/logger'
import type { Cradle } from '../container'

type AsyncFn<T> = (...args: any[]) => Promise<T>

Expand All @@ -12,9 +12,13 @@ interface DedupeOptions {
}

export class Deduplicator {
private logger: Cradle['logger']

private cache: Map<string, CacheEntry> = new Map()

constructor(private logger: Logger) {}
constructor({ logger }: Cradle) {
Object.assign(this, { logger })
}

dedupe<T extends AsyncFn<any>>(
fn: T,
Expand Down
8 changes: 6 additions & 2 deletions src/background/services/heartbeat.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import type { Browser } from 'webextension-polyfill'
import type { Cradle } from '@/background/container'

export class Heartbeat {
constructor(private browser: Browser) {}
private browser: Cradle['browser']

constructor({ browser }: Cradle) {
Object.assign(this, { browser })
}

start() {
const alarms = this.browser.alarms
Expand Down
52 changes: 30 additions & 22 deletions src/background/services/monetization.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import type {
EventsService,
OpenPaymentsService,
StorageService,
TabState
} from '.'
import { type Browser, type Runtime } from 'webextension-polyfill'
import { Logger } from '@/shared/logger'
import type { Runtime } from 'webextension-polyfill'
import {
ResumeMonetizationPayload,
StartMonetizationPayload,
Expand All @@ -15,24 +8,39 @@ import { PaymentSession } from './paymentSession'
import { emitToggleWM } from '../lib/messages'
import { computeRate, getCurrentActiveTab, getSender, getTabId } from '../utils'
import { isOutOfBalanceError } from './openPayments'
import {
isOkState,
removeQueryParams,
type Translation
} from '@/shared/helpers'
import { isOkState, removeQueryParams } from '@/shared/helpers'
import { ALLOWED_PROTOCOLS } from '@/shared/defines'
import type { AmountValue, PopupStore, Storage } from '@/shared/types'
import type { Cradle } from '../container'

export class MonetizationService {
constructor(
private logger: Logger,
private t: Translation,
private openPaymentsService: OpenPaymentsService,
private storage: StorageService,
private browser: Browser,
private events: EventsService,
private tabState: TabState
) {
private logger: Cradle['logger']
private t: Cradle['t']
private openPaymentsService: Cradle['openPaymentsService']
private storage: Cradle['storage']
private browser: Cradle['browser']
private events: Cradle['events']
private tabState: Cradle['tabState']

constructor({
logger,
t,
browser,
storage,
events,
openPaymentsService,
tabState
}: Cradle) {
Object.assign(this, {
logger,
t,
openPaymentsService,
storage,
browser,
events,
tabState
})

this.registerEventListeners()
}

Expand Down
24 changes: 12 additions & 12 deletions src/background/services/openPayments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,19 @@ import * as ed from '@noble/ed25519'
import { type Request } from 'http-message-signatures'
import { signMessage } from 'http-message-signatures/lib/httpbis'
import { createContentDigestHeader } from 'httpbis-digest-headers'
import { Browser, Tabs } from 'webextension-polyfill'
import { Tabs } from 'webextension-polyfill'
import { getExchangeRates, getRateOfPay, toAmount } from '../utils'
import { StorageService } from '@/background/services/storage'
import { exportJWK, generateEd25519KeyPair } from '@/shared/crypto'
import { bytesToHex } from '@noble/hashes/utils'
import { getWalletInformation, type Translation } from '@/shared/helpers'
import { getWalletInformation } from '@/shared/helpers'
import { AddFundsPayload, ConnectWalletPayload } from '@/shared/messages'
import {
DEFAULT_RATE_OF_PAY,
MAX_RATE_OF_PAY,
MIN_RATE_OF_PAY
} from '../config'
import type { Deduplicator } from './deduplicator'
import type { Logger } from '@/shared/logger'
import { OPEN_PAYMENTS_REDIRECT_URL } from '@/shared/defines'
import type { Cradle } from '../container'

interface KeyInformation {
privateKey: string
Expand Down Expand Up @@ -108,6 +106,12 @@ const enum InteractionIntent {
}

export class OpenPaymentsService {
private browser: Cradle['browser']
private storage: Cradle['storage']
private deduplicator: Cradle['deduplicator']
private logger: Cradle['logger']
private t: Cradle['t']

client?: AuthenticatedClient

public switchGrant: OpenPaymentsService['_switchGrant']
Expand All @@ -117,13 +121,9 @@ export class OpenPaymentsService {
/** Whether a grant has enough balance to make payments */
private isGrantUsable = { recurring: false, oneTime: false }

constructor(
private browser: Browser,
private storage: StorageService,
private deduplicator: Deduplicator,
private logger: Logger,
private t: Translation
) {
constructor({ browser, storage, deduplicator, logger, t }: Cradle) {
Object.assign(this, { browser, storage, deduplicator, logger, t })

void this.initialize()
this.switchGrant = this.deduplicator.dedupe(this._switchGrant.bind(this))
}
Expand Down
9 changes: 7 additions & 2 deletions src/background/services/sendToPopup.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import type { Browser, Runtime } from 'webextension-polyfill'
import type { Runtime } from 'webextension-polyfill'
import {
BACKGROUND_TO_POPUP_CONNECTION_NAME as CONNECTION_NAME,
type BackgroundToPopupMessage,
type BackgroundToPopupMessagesMap
} from '@/shared/messages'
import type { Cradle } from '@/background/container'

export class SendToPopup {
private browser: Cradle['browser']

private isConnected = false
private port: Runtime.Port
private queue = new Map<keyof BackgroundToPopupMessagesMap, any>()

constructor(private browser: Browser) {}
constructor({ browser }: Cradle) {
Object.assign(this, { browser })
}

start() {
this.browser.runtime.onConnect.addListener((port) => {
Expand Down
13 changes: 7 additions & 6 deletions src/background/services/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ import type {
StorageKey,
WalletAmount
} from '@/shared/types'
import { type Browser } from 'webextension-polyfill'
import { EventsService } from './events'
import { bigIntMax, objectEquals, ThrottleBatch } from '@/shared/helpers'
import { computeBalance } from '../utils'
import type { Cradle } from '../container'

const defaultStorage = {
/**
Expand All @@ -35,15 +34,17 @@ const defaultStorage = {
} satisfies Omit<Storage, 'publicKey' | 'privateKey' | 'keyId'>

export class StorageService {
private browser: Cradle['browser']
private events: Cradle['events']

private setSpentAmountRecurring: ThrottleBatch<[amount: string]>
private setSpentAmountOneTime: ThrottleBatch<[amount: string]>
// used as an optimization/cache
private currentState: Storage['state'] | null = null

constructor(
private browser: Browser,
private events: EventsService
) {
constructor({ browser, events }: Cradle) {
Object.assign(this, { browser, events })

this.setSpentAmountRecurring = new ThrottleBatch(
(amount) => this.setSpentAmount('recurring', amount),
(args) => [args.reduce((max, [v]) => bigIntMax(max, v), '0')],
Expand Down
30 changes: 17 additions & 13 deletions src/background/services/tabEvents.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import browser from 'webextension-polyfill'
import type { Browser } from 'webextension-polyfill'
import {
isOkState,
removeQueryParams,
type Translation
} from '@/shared/helpers'
import type { SendToPopup, StorageService, TabState } from '.'
import { isOkState, removeQueryParams } from '@/shared/helpers'
import type { Storage, TabId } from '@/shared/types'
import type { Cradle } from '@/background/container'

const runtime = browser.runtime
const ICONS = {
Expand Down Expand Up @@ -56,13 +52,21 @@ type CallbackTab<T extends Extract<keyof Browser['tabs'], `on${string}`>> =
Parameters<Browser['tabs'][T]['addListener']>[0]

export class TabEvents {
constructor(
private storage: StorageService,
private tabState: TabState,
private sendToPopup: SendToPopup,
private t: Translation,
private browser: Browser
) {}
private storage: Cradle['storage']
private tabState: Cradle['tabState']
private sendToPopup: Cradle['sendToPopup']
private t: Cradle['t']
private browser: Cradle['browser']

constructor({ storage, tabState, sendToPopup, t, browser }: Cradle) {
Object.assign(this, {
storage,
tabState,
sendToPopup,
t,
browser
})
}

onUpdatedTab: CallbackTab<'onUpdated'> = (tabId, changeInfo, tab) => {
/**
Expand Down
10 changes: 8 additions & 2 deletions src/background/services/tabState.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { MonetizationEventDetails } from '@/shared/messages'
import type { TabId } from '@/shared/types'
import type { PaymentSession } from './paymentSession'
import type { Logger } from '@/shared/logger'
import type { Cradle } from '@/background/container'

type State = {
monetizationEvent: MonetizationEventDetails
Expand All @@ -18,10 +18,16 @@ interface SaveOverpayingDetails {
type SessionId = string

export class TabState {
private logger: Cradle['logger']

private state = new Map<TabId, Map<string, State>>()
private sessions = new Map<TabId, Map<SessionId, PaymentSession>>()

constructor(private logger: Logger) {}
constructor({ logger }: Cradle) {
Object.assign(this, {
logger
})
}

private getOverpayingStateKey(url: string, walletAddressId: string): string {
return `${url}:${walletAddressId}`
Expand Down
4 changes: 2 additions & 2 deletions src/content/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { MonetizationTagManager } from './services/monetizationTagManager'
import { LOG_LEVEL } from '@/shared/defines'
import { FrameManager } from './services/frameManager'

interface Cradle {
export interface Cradle {
logger: Logger
browser: Browser
document: Document
Expand All @@ -18,7 +18,7 @@ interface Cradle {

export const configureContainer = () => {
const container = createContainer<Cradle>({
injectionMode: InjectionMode.CLASSIC
injectionMode: InjectionMode.PROXY
})

const logger = createLogger(LOG_LEVEL)
Expand Down
Loading

0 comments on commit 40b21c2

Please sign in to comment.