From fbe1610200f3e478e736757a350f266213eac61f Mon Sep 17 00:00:00 2001 From: Nate Reprogle Date: Fri, 15 Aug 2025 16:01:56 -0500 Subject: [PATCH 1/5] Work on making defineProxyService shakable. One test is failing and I'm not sure why --- bun.lockb | Bin 585552 -> 593560 bytes .../proxy-service/1.defining-services.md | 63 ++++++----- docs/content/proxy-service/api.md | 35 ++++++ .../src/entrypoints/background.ts | 5 +- .../src/entrypoints/popup/main.ts | 2 + .../src/utils/math-service.ts | 10 +- .../src/defineProxyService.test.ts | 102 +++++++++++++++++- .../proxy-service/src/defineProxyService.ts | 86 +++++++++++++++ packages/proxy-service/src/index.ts | 2 +- 9 files changed, 263 insertions(+), 42 deletions(-) diff --git a/bun.lockb b/bun.lockb index 68eb4fcd958edbb775296d0e5c1dbbc83503ff78..c5ace0477527d688e9b454f96e942a5ccfb14148 100755 GIT binary patch delta 94556 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 {} async getAll(): Promise { @@ -18,16 +18,13 @@ class TodosRepo { } } -export const [registerTodosRepo, getTodosRepo] = defineProxyService( - 'TodosRepo', - (idb: Promise) => new TodosRepo(idb), -); +export const [registerTodosRepo, getTodosRepo] = defineShakableProxyService('TodosRepo'); ``` ```ts // Register const db = openDB('todos'); -registerTodosRepo(db); +registerTodosRepo((idb: Promise) => new TodosRepo(idb), db); ``` ```ts @@ -44,22 +41,22 @@ Objects can be used as services as well. All functions defined on the object are import { openDB, IDBPDatabase } from 'idb'; import { defineProxyService } from '@webext-core/proxy-service'; -export const [registerTodosRepo, getTodosRepo] = defineProxyService( - 'TodosRepo', +export const [registerTodosRepo, getTodosRepo] = defineShakableProxyService('TodosRepo'); +``` + +```ts +// Register +const db = openDB('todos'); +registerTodosRepo( (db: Promise) => ({ async getAll(): Promise { return (await this.db).getAll('todos'); }, }), + db, ); ``` -```ts -// Register -const db = openDB('todos'); -registerTodosRepo(db); -``` - ```ts // Get an instance const todosRepo = getTodosRepo(); @@ -74,19 +71,18 @@ If you only need to define a single function, you can! import { openDB, IDBPDatabase } from 'idb'; import { defineProxyService } from '@webext-core/proxy-service'; -export const [registerGetAllTodos, getGetAllTodos] = defineProxyService( - 'TodosRepo', - (db: Promise) => - function getAllTodos() { - return (await this.db).getAll('todos'); - }, -); +export function getAllTodos(db: Promise) { + return (await db).getAll('todos'); +} + +export const [registerGetAllTodos, getGetAllTodos] = + defineShakableProxyService('TodosRepo'); ``` ```ts // Register const db = openDB('todos'); -registerGetAllTodos(db); +registerGetAllTodos((db: Promise) => getAllTodos, db); ``` ```ts @@ -103,7 +99,7 @@ If you need to register "deep" objects containing multiple services, you can do import { openDB, IDBPDatabase } from 'idb'; import { defineProxyService } from '@webext-core/proxy-service'; -class TodosRepo { +export class TodosRepo { constructor(private db: Promise) {} async getAll(): Promise { @@ -111,26 +107,27 @@ class TodosRepo { } } -const createAuthorsRepo = (db: Promise) => ({ +export const createAuthorsRepo = (db: Promise) => ({ async getOne(id: string): Promise { return (await this.db).getAll('authors', id); }, }); -function createApi(db: Promise) { - return { - todos: new TodosRepo(db), - authors: createAuthorsRepo(db), - }; -} - -export const [registerApi, getApi] = defineProxyService('Api', createApi); +export const [registerApi, getApi] = defineShakableProxyService('Api'); ``` ```ts // Register const db = openDB('todos'); -registerApi(db); +registerApi( + (db: Promise) { + return { + todos: new TodosRepo(db), + authors: createAuthorsRepo(db), + }; + }, + db +); ``` ```ts diff --git a/docs/content/proxy-service/api.md b/docs/content/proxy-service/api.md index f14a6d1..4384c53 100644 --- a/docs/content/proxy-service/api.md +++ b/docs/content/proxy-service/api.md @@ -54,6 +54,41 @@ of the JS context the they are called from. - `registerService`: Used to register your service in the background - `getService`: Used to get an instance of the service anywhere in the extension. +### Deprecated + +Recommended to use `defineShakableProxyService`. + +## `defineShakableProxyService` + +```ts +function defineShakableProxyService( + name: string, + config?: ProxyServiceConfig, +): [ + registerService: ( + init: (...args: any[]) => TService | Promise, + ...args: any[] + ) => Promise, + getService: () => ProxyService +] { + // ... +} +``` + +Utility for creating a service whose functions are executed in the background script regardless +of the JS context the they are called from. + +### Parameters + +- ***`name: string`***
A unique name for the service. Used to identify which service is being executed. + +- ***`config?: ProxyServiceConfig`***
An object that allows configuration of the underlying messaging service + +### Returns + +- `registerService`: Used to register your service in the background. Requires an `init()` callback used to create the actual service object. +- `getService`: Used to get an instance of the service anywhere in the extension. + ## `flattenPromise` ```ts diff --git a/packages/proxy-service-demo/src/entrypoints/background.ts b/packages/proxy-service-demo/src/entrypoints/background.ts index c8b65c1..016135e 100644 --- a/packages/proxy-service-demo/src/entrypoints/background.ts +++ b/packages/proxy-service-demo/src/entrypoints/background.ts @@ -1,3 +1,6 @@ export default defineBackground(() => { - registerMathService(); + registerMathService(async () => { + const { MathService } = await import('../utils/math-service'); + return new MathService(); + }); }); diff --git a/packages/proxy-service-demo/src/entrypoints/popup/main.ts b/packages/proxy-service-demo/src/entrypoints/popup/main.ts index d1414f7..648ddaa 100644 --- a/packages/proxy-service-demo/src/entrypoints/popup/main.ts +++ b/packages/proxy-service-demo/src/entrypoints/popup/main.ts @@ -1,3 +1,5 @@ +import { getMathService } from '../../utils/math-service'; + function getMathServiceElements(id: string) { const parent = document.getElementById(id)!; return [ diff --git a/packages/proxy-service-demo/src/utils/math-service.ts b/packages/proxy-service-demo/src/utils/math-service.ts index 2cde22b..fa30c57 100644 --- a/packages/proxy-service-demo/src/utils/math-service.ts +++ b/packages/proxy-service-demo/src/utils/math-service.ts @@ -1,6 +1,6 @@ -import { defineProxyService } from '@webext-core/proxy-service'; +import { defineShakableProxyService } from '@webext-core/proxy-service'; -class MathService { +export class MathService { add(x: number, y: number): number { console.log(`MathService.add(${x}, ${y})`); return x + y; @@ -25,7 +25,5 @@ class MathService { } } -export const [registerMathService, getMathService] = defineProxyService( - 'MathService', - () => new MathService(), -); +export const [registerMathService, getMathService] = + defineShakableProxyService('MathService'); diff --git a/packages/proxy-service/src/defineProxyService.test.ts b/packages/proxy-service/src/defineProxyService.test.ts index 9a89250..8c7a20f 100644 --- a/packages/proxy-service/src/defineProxyService.test.ts +++ b/packages/proxy-service/src/defineProxyService.test.ts @@ -1,4 +1,4 @@ -import { defineProxyService } from './defineProxyService'; +import { defineProxyService, defineShakableProxyService } from './defineProxyService'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { isBackground } from './isBackground'; import { fakeBrowser } from '@webext-core/fake-browser'; @@ -16,6 +16,25 @@ const defineTestService = () => getNextVersion: () => Promise.resolve(version + 1), })); +class ShakableTestService { + private version: number; + + constructor(version: number) { + this.version = version; + } + + getVersion() { + return this.version; + } + + getNextVersion() { + return Promise.resolve(this.version + 1); + } +} + +const defineShakableTestService = () => + defineShakableProxyService('ShakableTestService'); + describe('defineProxyService', () => { beforeEach(() => { vi.resetAllMocks(); @@ -94,3 +113,84 @@ describe('defineProxyService', () => { expect(fn2).toBeCalledTimes(1); }); }); + +describe('defineShakableProxyService', () => { + beforeEach(() => { + vi.resetAllMocks(); + fakeBrowser.reset(); + }); + + it("getService should fail to get the service in the background if one hasn't been registered", () => { + const [_, getShakableTestService] = defineShakableTestService(); + isBackgroundMock.mockReturnValue(true); + + expect(getShakableTestService).toThrowError(); + }); + + it('getService should return a proxy in other contexts', () => { + const [registerShakableTestService, getShakableTestService] = defineShakableTestService(); + registerShakableTestService(() => new ShakableTestService(1)); + isBackgroundMock.mockReturnValue(false); + + // @ts-expect-error: __proxy is not apart of the type, but it's there + expect(getShakableTestService().__proxy).toEqual(true); + }); + + it('should defer execution of the proxy service methods to the real service methods', async () => { + const version = 10; + const [registerShakableTestService, getShakableTestService] = defineShakableTestService(); + registerShakableTestService(() => new ShakableTestService(10)); + + isBackgroundMock.mockReturnValue(true); + const real = getShakableTestService(); + isBackgroundMock.mockReturnValue(false); + const proxy = getShakableTestService(); + const realGetVersionSpy = vi.spyOn(real, 'getVersion'); + + const actual = await proxy.getVersion(); + + expect(actual).toEqual(version); + expect(realGetVersionSpy).toBeCalledTimes(1); + }); + + it('should support executing functions directly', async () => { + const expected = 5; + const fn: () => Promise = vi.fn().mockResolvedValue(expected); + const [registerFn, getFn] = defineShakableProxyService('fn'); + registerFn(() => fn); + + isBackgroundMock.mockReturnValue(false); + const proxyFn = getFn(); + + const actual = await proxyFn(); + + expect(actual).toBe(expected); + expect(fn).toBeCalledTimes(1); + }); + + it('should support executing deeply nested functions at multiple depths', async () => { + const expected1 = 5; + const expected2 = 6; + const fn1 = vi.fn<() => Promise>().mockResolvedValue(expected1); + const fn2 = vi.fn<() => Promise>().mockResolvedValue(expected2); + const deepObj = { + fn1, + path: { + to: { + fn2, + }, + }, + }; + const [registerDeepObject, getDeepObject] = + defineShakableProxyService('DeepObject'); + registerDeepObject(() => deepObj); + + isBackgroundMock.mockReturnValue(false); + const deepObject = getDeepObject(); + + await expect(deepObject.fn1()).resolves.toBe(expected1); + expect(fn1).toBeCalledTimes(1); + await expect(deepObject.path.to.fn2()).resolves.toBe(expected2); + expect(fn2).toBeCalledTimes(1); + }); +}); diff --git a/packages/proxy-service/src/defineProxyService.ts b/packages/proxy-service/src/defineProxyService.ts index 6794fbf..8688274 100644 --- a/packages/proxy-service/src/defineProxyService.ts +++ b/packages/proxy-service/src/defineProxyService.ts @@ -14,6 +14,7 @@ import get from 'get-value'; * @returns * - `registerService`: Used to register your service in the background * - `getService`: Used to get an instance of the service anywhere in the extension. + * @deprecated Use `defineShakableProxyService` instead. */ export function defineProxyService( name: string, @@ -80,3 +81,88 @@ export function defineProxyService( + name: string, + config?: ProxyServiceConfig, +): [ + registerService: ( + init: (...args: any[]) => TService | Promise, + ...args: any[] + ) => Promise, + getService: () => ProxyService, +] { + let service: TService | undefined; + + const messageKey = `proxy-service.${name}`; + const { onMessage, sendMessage } = defineExtensionMessaging<{ + [key: string]: ProtocolWithReturn<{ path?: string; args: any[] }, any>; + }>(config); + + /** + * Create and returns a "deep" proxy. Every property that is accessed returns another proxy, and + * when a function is called at any depth (0 to infinity), a message is sent to the background. + */ + function createProxy(path?: string): ProxyService { + const wrapped = (() => {}) as ProxyService; + const proxy = new Proxy(wrapped, { + // Executed when the object is called as a function + async apply(_target, _thisArg, args) { + const res = await sendMessage(messageKey, { + path, + args: args, + }); + return res; + }, + + // Executed when accessing a property on an object + get(target, propertyName, receiver) { + if (propertyName === '__proxy' || typeof propertyName === 'symbol') { + return Reflect.get(target, propertyName, receiver); + } + return createProxy(path == null ? propertyName : `${path}.${propertyName}`); + }, + }); + // @ts-expect-error: Adding a hidden property + proxy.__proxy = true; + return proxy; + } + + return [ + async function registerService( + init: (...args: TArgs) => TService | Promise, + ...args: TArgs + ): Promise { + service = await init(...args); + onMessage(messageKey, ({ data }) => { + const method = data.path == null ? service : get(service ?? {}, data.path); + if (method) return Promise.resolve(method.bind(service)(...data.args)); + }); + return service; + }, + + function getService() { + // Create proxy for non-background + if (!isBackground()) return createProxy(); + + // Register the service if it hasn't been registered yet + if (service == null) { + throw Error( + `Failed to get an instance of ${name}: in background, but registerService has not been called. Did you forget to call registerService?`, + ); + } + return service as ProxyService; + }, + ]; +} diff --git a/packages/proxy-service/src/index.ts b/packages/proxy-service/src/index.ts index a506956..7c2634f 100644 --- a/packages/proxy-service/src/index.ts +++ b/packages/proxy-service/src/index.ts @@ -1,3 +1,3 @@ -export { defineProxyService } from './defineProxyService'; +export { defineProxyService, defineShakableProxyService } from './defineProxyService'; export { flattenPromise } from './flattenPromise'; export type { ProxyServiceConfig, ProxyService, DeepAsync } from './types'; From 6ff8b1e133369a61d0ad8c8384bd731a8ae9922f Mon Sep 17 00:00:00 2001 From: Nate Reprogle Date: Fri, 15 Aug 2025 16:03:44 -0500 Subject: [PATCH 2/5] Update definition of registration --- packages/proxy-service/src/defineProxyService.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/proxy-service/src/defineProxyService.test.ts b/packages/proxy-service/src/defineProxyService.test.ts index 8c7a20f..a0e6083 100644 --- a/packages/proxy-service/src/defineProxyService.test.ts +++ b/packages/proxy-service/src/defineProxyService.test.ts @@ -139,7 +139,7 @@ describe('defineShakableProxyService', () => { it('should defer execution of the proxy service methods to the real service methods', async () => { const version = 10; const [registerShakableTestService, getShakableTestService] = defineShakableTestService(); - registerShakableTestService(() => new ShakableTestService(10)); + registerShakableTestService((ver: number) => new ShakableTestService(ver), version); isBackgroundMock.mockReturnValue(true); const real = getShakableTestService(); From 8820956a184243787017340e497ee42d3d1edff7 Mon Sep 17 00:00:00 2001 From: Nate Reprogle Date: Fri, 15 Aug 2025 16:08:17 -0500 Subject: [PATCH 3/5] Async race condition was causing failures. Removed ability to make async proxy initializers. --- packages/proxy-service/src/defineProxyService.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/proxy-service/src/defineProxyService.ts b/packages/proxy-service/src/defineProxyService.ts index 8688274..01f358d 100644 --- a/packages/proxy-service/src/defineProxyService.ts +++ b/packages/proxy-service/src/defineProxyService.ts @@ -97,10 +97,7 @@ export function defineShakableProxyService( name: string, config?: ProxyServiceConfig, ): [ - registerService: ( - init: (...args: any[]) => TService | Promise, - ...args: any[] - ) => Promise, + registerService: (init: (...args: any[]) => TService, ...args: any[]) => Promise, getService: () => ProxyService, ] { let service: TService | undefined; @@ -141,10 +138,10 @@ export function defineShakableProxyService( return [ async function registerService( - init: (...args: TArgs) => TService | Promise, + init: (...args: TArgs) => TService, ...args: TArgs ): Promise { - service = await init(...args); + service = init(...args); onMessage(messageKey, ({ data }) => { const method = data.path == null ? service : get(service ?? {}, data.path); if (method) return Promise.resolve(method.bind(service)(...data.args)); From b94b168bcc805ed891da3a196f87408eeec65e84 Mon Sep 17 00:00:00 2001 From: Nate Reprogle Date: Fri, 15 Aug 2025 16:10:31 -0500 Subject: [PATCH 4/5] Remove all promises from shakable tree proxy entirely. Don't make async what isn't async --- docs/content/proxy-service/api.md | 4 ++-- packages/proxy-service/src/defineProxyService.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/content/proxy-service/api.md b/docs/content/proxy-service/api.md index 4384c53..7963cf5 100644 --- a/docs/content/proxy-service/api.md +++ b/docs/content/proxy-service/api.md @@ -66,9 +66,9 @@ function defineShakableProxyService( config?: ProxyServiceConfig, ): [ registerService: ( - init: (...args: any[]) => TService | Promise, + init: (...args: any[]) => TService, ...args: any[] - ) => Promise, + ) => TService, getService: () => ProxyService ] { // ... diff --git a/packages/proxy-service/src/defineProxyService.ts b/packages/proxy-service/src/defineProxyService.ts index 01f358d..c36923b 100644 --- a/packages/proxy-service/src/defineProxyService.ts +++ b/packages/proxy-service/src/defineProxyService.ts @@ -97,7 +97,7 @@ export function defineShakableProxyService( name: string, config?: ProxyServiceConfig, ): [ - registerService: (init: (...args: any[]) => TService, ...args: any[]) => Promise, + registerService: (init: (...args: any[]) => TService, ...args: any[]) => TService, getService: () => ProxyService, ] { let service: TService | undefined; @@ -137,10 +137,10 @@ export function defineShakableProxyService( } return [ - async function registerService( + function registerService( init: (...args: TArgs) => TService, ...args: TArgs - ): Promise { + ): TService { service = init(...args); onMessage(messageKey, ({ data }) => { const method = data.path == null ? service : get(service ?? {}, data.path); From 5283ba9849d0c5eed26af408f4e92abe9a7661c0 Mon Sep 17 00:00:00 2001 From: Nate Reprogle Date: Fri, 15 Aug 2025 19:41:41 -0500 Subject: [PATCH 5/5] Finish tree shaking functionality. Had to end up writing defineServiceProxy as async due to dynamic imports. Fix issue with docs compilation. --- docs/content/messaging/api.md | 24 ++-- docs/content/proxy-service/0.installation.md | 12 +- .../proxy-service/1.defining-services.md | 37 +++--- docs/content/proxy-service/api.md | 22 ++-- .../src/utils/math-service.ts | 5 +- .../src/defineProxyService.test.ts | 102 +--------------- .../proxy-service/src/defineProxyService.ts | 86 +------------- .../src/defineServiceProxy.test.ts | 110 ++++++++++++++++++ .../proxy-service/src/defineServiceProxy.ts | 89 ++++++++++++++ packages/proxy-service/src/index.ts | 3 +- 10 files changed, 257 insertions(+), 233 deletions(-) create mode 100644 packages/proxy-service/src/defineServiceProxy.test.ts create mode 100644 packages/proxy-service/src/defineServiceProxy.ts diff --git a/docs/content/messaging/api.md b/docs/content/messaging/api.md index 19aa8a5..6275f8a 100644 --- a/docs/content/messaging/api.md +++ b/docs/content/messaging/api.md @@ -19,7 +19,7 @@ interface BaseMessagingConfig { Shared configuration between all the different messengers. -### Properties +### Properties - ***`logger?: Logger`*** (default: `console`)
The logger to use when logging messages. Set to `null` to disable logging. @@ -35,7 +35,7 @@ interface CustomEventMessage { Additional fields available on the `Message` from a `CustomEventMessenger`. -### Properties +### Properties - ***`event: CustomEvent`***
The event that was fired, resulting in the message being passed. @@ -153,7 +153,7 @@ interface ExtensionMessage { Additional fields available on the `Message` from an `ExtensionMessenger`. -### Properties +### Properties - ***`sender: Runtime.MessageSender`***
Information about where the message came from. See [`Runtime.MessageSender`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/MessageSender). @@ -196,6 +196,12 @@ interface GenericMessenger< TMessageExtension, TSendMessageArgs extends any[], > { + sendMessage( + type: TType, + ...args: GetDataType extends undefined + ? [data?: undefined, ...args: TSendMessageArgs] + : never + ): Promise>; sendMessage( type: TType, data: GetDataType, @@ -283,7 +289,7 @@ interface Message< Contains information about the message received. -### Properties +### Properties - ***`id: number`***
A semi-unique, auto-incrementing number used to trace messages being sent. @@ -306,7 +312,7 @@ interface MessageSender { An object containing information about the script context that sent a message or request. -### Properties +### Properties - ***`tab?: Tabs.Tab`***
The $(ref:tabs.Tab) which opened the connection, if any. This property will only be present when the connection was opened from a tab (including content scripts), and only @@ -332,7 +338,7 @@ interface NamespaceMessagingConfig extends BaseMessagingConfig { } ``` -### Properties +### Properties - ***`namespace: string`***
A string used to ensure the messenger only sends messages to and listens for messages from other messengers of the same type, with the same namespace. @@ -354,7 +360,7 @@ Used to add a return type to a message in the protocol map. > Internally, this is just an object with random keys for the data and return types. -### Properties +### Properties - ***`BtVgCTPYZu: TData`***
Stores the data type. Randomly named so that it isn't accidentally implemented. @@ -392,7 +398,7 @@ interface SendMessageOptions { Options for sending a message to a specific tab/frame -### Properties +### Properties - ***`tabId: number`***
The tab to send a message to @@ -429,4 +435,4 @@ details. --- -_API reference generated by [`docs/generate-api-references.ts`](https://github.com/aklinker1/webext-core/blob/main/docs/generate-api-references.ts)_ +_API reference generated by [`docs/generate-api-references.ts`](https://github.com/aklinker1/webext-core/blob/main/docs/generate-api-references.ts)_ \ No newline at end of file diff --git a/docs/content/proxy-service/0.installation.md b/docs/content/proxy-service/0.installation.md index bf8512f..fcc32c3 100644 --- a/docs/content/proxy-service/0.installation.md +++ b/docs/content/proxy-service/0.installation.md @@ -17,17 +17,19 @@ class MathService { ... } } -export const [registerMathService, getMathService] = defineProxyService( - 'MathService', - () => new MathService(), -); +export const [registerMathService, getMathService] = defineServiceProxy('MathService'); ``` ```ts [background.ts] import { registerMathService } from './MathService'; // 2. Register the service at the beginning of the background script -registerMathService(); +export default defineBackground(() => { + registerMathService(async () => { + const { MathService } = await import('../utils/math-service'); + return new MathService(); + }); +}); ``` ```ts [anywhere-else.ts] diff --git a/docs/content/proxy-service/1.defining-services.md b/docs/content/proxy-service/1.defining-services.md index 8a0563c..2ea848d 100644 --- a/docs/content/proxy-service/1.defining-services.md +++ b/docs/content/proxy-service/1.defining-services.md @@ -8,7 +8,7 @@ Define a class whose methods are available in other JS contexts: ```ts import { openDB, IDBPDatabase } from 'idb'; -import { defineProxyService } from '@webext-core/proxy-service'; +import { defineServiceProxy } from '@webext-core/proxy-service'; export class TodosRepo { constructor(private db: Promise) {} @@ -18,7 +18,7 @@ export class TodosRepo { } } -export const [registerTodosRepo, getTodosRepo] = defineShakableProxyService('TodosRepo'); +export const [registerTodosRepo, getTodosRepo] = defineServiceProxy('TodosRepo'); ``` ```ts @@ -39,15 +39,15 @@ Objects can be used as services as well. All functions defined on the object are ```ts import { openDB, IDBPDatabase } from 'idb'; -import { defineProxyService } from '@webext-core/proxy-service'; +import { defineServiceProxy } from '@webext-core/proxy-service'; -export const [registerTodosRepo, getTodosRepo] = defineShakableProxyService('TodosRepo'); +export const [registerTodosRepo, getTodosRepo] = defineServiceProxy('TodosRepo'); ``` ```ts // Register const db = openDB('todos'); -registerTodosRepo( +await registerTodosRepo( (db: Promise) => ({ async getAll(): Promise { return (await this.db).getAll('todos'); @@ -69,20 +69,20 @@ If you only need to define a single function, you can! ```ts import { openDB, IDBPDatabase } from 'idb'; -import { defineProxyService } from '@webext-core/proxy-service'; +import { defineServiceProxy } from '@webext-core/proxy-service'; -export function getAllTodos(db: Promise) { +export async function getAllTodos(db: Promise) { return (await db).getAll('todos'); } export const [registerGetAllTodos, getGetAllTodos] = - defineShakableProxyService('TodosRepo'); + defineServiceProxy('TodosRepo'); ``` ```ts // Register const db = openDB('todos'); -registerGetAllTodos((db: Promise) => getAllTodos, db); +await registerGetAllTodos((db: Promise) => getAllTodos, db); ``` ```ts @@ -97,7 +97,7 @@ If you need to register "deep" objects containing multiple services, you can do ```ts import { openDB, IDBPDatabase } from 'idb'; -import { defineProxyService } from '@webext-core/proxy-service'; +import { defineServiceProxy } from '@webext-core/proxy-service'; export class TodosRepo { constructor(private db: Promise) {} @@ -113,21 +113,18 @@ export const createAuthorsRepo = (db: Promise) => ({ }, }); -export const [registerApi, getApi] = defineShakableProxyService('Api'); +export const [registerApi, getApi] = defineServiceProxy('Api'); ``` ```ts // Register const db = openDB('todos'); -registerApi( - (db: Promise) { - return { - todos: new TodosRepo(db), - authors: createAuthorsRepo(db), - }; - }, - db -); +await registerApi((db: Promise) => { + return { + todos: new TodosRepo(db), + authors: reateAuthorsRepo(db), + }; +}, db); ``` ```ts diff --git a/docs/content/proxy-service/api.md b/docs/content/proxy-service/api.md index 7963cf5..0e9f883 100644 --- a/docs/content/proxy-service/api.md +++ b/docs/content/proxy-service/api.md @@ -24,6 +24,10 @@ A recursive type that deeply converts all methods in `TService` to be async. ## `defineProxyService` +:::danger Deprecated +Use {@link defineServiceProxy } instead. +::: + ```ts function defineProxyService( name: string, @@ -54,35 +58,31 @@ of the JS context the they are called from. - `registerService`: Used to register your service in the background - `getService`: Used to get an instance of the service anywhere in the extension. -### Deprecated - -Recommended to use `defineShakableProxyService`. - -## `defineShakableProxyService` +## `defineServiceProxy` ```ts -function defineShakableProxyService( +function defineServiceProxy( name: string, config?: ProxyServiceConfig, ): [ registerService: ( - init: (...args: any[]) => TService, + init: (...args: any[]) => TService | Promise, ...args: any[] - ) => TService, - getService: () => ProxyService + ) => Promise, + getService: () => ProxyService, ] { // ... } ``` Utility for creating a service whose functions are executed in the background script regardless -of the JS context the they are called from. +of the JS context they are called from. ### Parameters - ***`name: string`***
A unique name for the service. Used to identify which service is being executed. -- ***`config?: ProxyServiceConfig`***
An object that allows configuration of the underlying messaging service +- ***`config?: ProxyServiceConfig`***
An object that allows configuration of the underlying messaging service ### Returns diff --git a/packages/proxy-service-demo/src/utils/math-service.ts b/packages/proxy-service-demo/src/utils/math-service.ts index fa30c57..3aae2bd 100644 --- a/packages/proxy-service-demo/src/utils/math-service.ts +++ b/packages/proxy-service-demo/src/utils/math-service.ts @@ -1,4 +1,4 @@ -import { defineShakableProxyService } from '@webext-core/proxy-service'; +import { defineServiceProxy } from '@webext-core/proxy-service'; export class MathService { add(x: number, y: number): number { @@ -25,5 +25,4 @@ export class MathService { } } -export const [registerMathService, getMathService] = - defineShakableProxyService('MathService'); +export const [registerMathService, getMathService] = defineServiceProxy('MathService'); diff --git a/packages/proxy-service/src/defineProxyService.test.ts b/packages/proxy-service/src/defineProxyService.test.ts index a0e6083..9a89250 100644 --- a/packages/proxy-service/src/defineProxyService.test.ts +++ b/packages/proxy-service/src/defineProxyService.test.ts @@ -1,4 +1,4 @@ -import { defineProxyService, defineShakableProxyService } from './defineProxyService'; +import { defineProxyService } from './defineProxyService'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { isBackground } from './isBackground'; import { fakeBrowser } from '@webext-core/fake-browser'; @@ -16,25 +16,6 @@ const defineTestService = () => getNextVersion: () => Promise.resolve(version + 1), })); -class ShakableTestService { - private version: number; - - constructor(version: number) { - this.version = version; - } - - getVersion() { - return this.version; - } - - getNextVersion() { - return Promise.resolve(this.version + 1); - } -} - -const defineShakableTestService = () => - defineShakableProxyService('ShakableTestService'); - describe('defineProxyService', () => { beforeEach(() => { vi.resetAllMocks(); @@ -113,84 +94,3 @@ describe('defineProxyService', () => { expect(fn2).toBeCalledTimes(1); }); }); - -describe('defineShakableProxyService', () => { - beforeEach(() => { - vi.resetAllMocks(); - fakeBrowser.reset(); - }); - - it("getService should fail to get the service in the background if one hasn't been registered", () => { - const [_, getShakableTestService] = defineShakableTestService(); - isBackgroundMock.mockReturnValue(true); - - expect(getShakableTestService).toThrowError(); - }); - - it('getService should return a proxy in other contexts', () => { - const [registerShakableTestService, getShakableTestService] = defineShakableTestService(); - registerShakableTestService(() => new ShakableTestService(1)); - isBackgroundMock.mockReturnValue(false); - - // @ts-expect-error: __proxy is not apart of the type, but it's there - expect(getShakableTestService().__proxy).toEqual(true); - }); - - it('should defer execution of the proxy service methods to the real service methods', async () => { - const version = 10; - const [registerShakableTestService, getShakableTestService] = defineShakableTestService(); - registerShakableTestService((ver: number) => new ShakableTestService(ver), version); - - isBackgroundMock.mockReturnValue(true); - const real = getShakableTestService(); - isBackgroundMock.mockReturnValue(false); - const proxy = getShakableTestService(); - const realGetVersionSpy = vi.spyOn(real, 'getVersion'); - - const actual = await proxy.getVersion(); - - expect(actual).toEqual(version); - expect(realGetVersionSpy).toBeCalledTimes(1); - }); - - it('should support executing functions directly', async () => { - const expected = 5; - const fn: () => Promise = vi.fn().mockResolvedValue(expected); - const [registerFn, getFn] = defineShakableProxyService('fn'); - registerFn(() => fn); - - isBackgroundMock.mockReturnValue(false); - const proxyFn = getFn(); - - const actual = await proxyFn(); - - expect(actual).toBe(expected); - expect(fn).toBeCalledTimes(1); - }); - - it('should support executing deeply nested functions at multiple depths', async () => { - const expected1 = 5; - const expected2 = 6; - const fn1 = vi.fn<() => Promise>().mockResolvedValue(expected1); - const fn2 = vi.fn<() => Promise>().mockResolvedValue(expected2); - const deepObj = { - fn1, - path: { - to: { - fn2, - }, - }, - }; - const [registerDeepObject, getDeepObject] = - defineShakableProxyService('DeepObject'); - registerDeepObject(() => deepObj); - - isBackgroundMock.mockReturnValue(false); - const deepObject = getDeepObject(); - - await expect(deepObject.fn1()).resolves.toBe(expected1); - expect(fn1).toBeCalledTimes(1); - await expect(deepObject.path.to.fn2()).resolves.toBe(expected2); - expect(fn2).toBeCalledTimes(1); - }); -}); diff --git a/packages/proxy-service/src/defineProxyService.ts b/packages/proxy-service/src/defineProxyService.ts index c36923b..ba5134e 100644 --- a/packages/proxy-service/src/defineProxyService.ts +++ b/packages/proxy-service/src/defineProxyService.ts @@ -14,7 +14,9 @@ import get from 'get-value'; * @returns * - `registerService`: Used to register your service in the background * - `getService`: Used to get an instance of the service anywhere in the extension. - * @deprecated Use `defineShakableProxyService` instead. + * + * @deprecated + * Use {@link defineServiceProxy} instead. */ export function defineProxyService( name: string, @@ -81,85 +83,3 @@ export function defineProxyService( - name: string, - config?: ProxyServiceConfig, -): [ - registerService: (init: (...args: any[]) => TService, ...args: any[]) => TService, - getService: () => ProxyService, -] { - let service: TService | undefined; - - const messageKey = `proxy-service.${name}`; - const { onMessage, sendMessage } = defineExtensionMessaging<{ - [key: string]: ProtocolWithReturn<{ path?: string; args: any[] }, any>; - }>(config); - - /** - * Create and returns a "deep" proxy. Every property that is accessed returns another proxy, and - * when a function is called at any depth (0 to infinity), a message is sent to the background. - */ - function createProxy(path?: string): ProxyService { - const wrapped = (() => {}) as ProxyService; - const proxy = new Proxy(wrapped, { - // Executed when the object is called as a function - async apply(_target, _thisArg, args) { - const res = await sendMessage(messageKey, { - path, - args: args, - }); - return res; - }, - - // Executed when accessing a property on an object - get(target, propertyName, receiver) { - if (propertyName === '__proxy' || typeof propertyName === 'symbol') { - return Reflect.get(target, propertyName, receiver); - } - return createProxy(path == null ? propertyName : `${path}.${propertyName}`); - }, - }); - // @ts-expect-error: Adding a hidden property - proxy.__proxy = true; - return proxy; - } - - return [ - function registerService( - init: (...args: TArgs) => TService, - ...args: TArgs - ): TService { - service = init(...args); - onMessage(messageKey, ({ data }) => { - const method = data.path == null ? service : get(service ?? {}, data.path); - if (method) return Promise.resolve(method.bind(service)(...data.args)); - }); - return service; - }, - - function getService() { - // Create proxy for non-background - if (!isBackground()) return createProxy(); - - // Register the service if it hasn't been registered yet - if (service == null) { - throw Error( - `Failed to get an instance of ${name}: in background, but registerService has not been called. Did you forget to call registerService?`, - ); - } - return service as ProxyService; - }, - ]; -} diff --git a/packages/proxy-service/src/defineServiceProxy.test.ts b/packages/proxy-service/src/defineServiceProxy.test.ts new file mode 100644 index 0000000..af037c5 --- /dev/null +++ b/packages/proxy-service/src/defineServiceProxy.test.ts @@ -0,0 +1,110 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { fakeBrowser } from '@webext-core/fake-browser'; +import { defineServiceProxy } from './defineServiceProxy'; +import { isBackground } from './isBackground'; + +vi.mock('webextension-polyfill'); + +vi.mock('./isBackground', () => ({ + isBackground: vi.fn(), +})); +const isBackgroundMock = vi.mocked(isBackground); + +class ShakableTestService { + private version: number; + + constructor(version: number) { + this.version = version; + } + + getVersion() { + return this.version; + } + + getNextVersion() { + return Promise.resolve(this.version + 1); + } +} + +const defineShakableTestService = () => + defineServiceProxy('ShakableTestService'); + +describe('defineServiceProxy', () => { + beforeEach(() => { + vi.resetAllMocks(); + fakeBrowser.reset(); + }); + + it("getService should fail to get the service in the background if one hasn't been registered", () => { + const [_, getShakableTestService] = defineShakableTestService(); + isBackgroundMock.mockReturnValue(true); + + expect(getShakableTestService).toThrowError(); + }); + + it('getService should return a proxy in other contexts', () => { + const [registerShakableTestService, getShakableTestService] = defineShakableTestService(); + registerShakableTestService(() => new ShakableTestService(1)); + isBackgroundMock.mockReturnValue(false); + + // @ts-expect-error: __proxy is not apart of the type, but it's there + expect(getShakableTestService().__proxy).toEqual(true); + }); + + it('should defer execution of the proxy service methods to the real service methods', async () => { + const version = 10; + const [registerShakableTestService, getShakableTestService] = defineShakableTestService(); + await registerShakableTestService((ver: number) => new ShakableTestService(ver), version); + + isBackgroundMock.mockReturnValue(true); + const real = getShakableTestService(); + isBackgroundMock.mockReturnValue(false); + const proxy = getShakableTestService(); + const realGetVersionSpy = vi.spyOn(real, 'getVersion'); + + const actual = await proxy.getVersion(); + + expect(actual).toEqual(version); + expect(realGetVersionSpy).toBeCalledTimes(1); + }); + + it('should support executing functions directly', async () => { + const expected = 5; + const fn: () => Promise = vi.fn().mockResolvedValue(expected); + const [registerFn, getFn] = defineServiceProxy('fn'); + registerFn(() => fn); + + isBackgroundMock.mockReturnValue(false); + const proxyFn = getFn(); + + const actual = await proxyFn(); + + expect(actual).toBe(expected); + expect(fn).toBeCalledTimes(1); + }); + + it('should support executing deeply nested functions at multiple depths', async () => { + const expected1 = 5; + const expected2 = 6; + const fn1 = vi.fn<() => Promise>().mockResolvedValue(expected1); + const fn2 = vi.fn<() => Promise>().mockResolvedValue(expected2); + const deepObj = { + fn1, + path: { + to: { + fn2, + }, + }, + }; + const [registerDeepObject, getDeepObject] = defineServiceProxy('DeepObject'); + registerDeepObject(() => deepObj); + + isBackgroundMock.mockReturnValue(false); + const deepObject = getDeepObject(); + + await expect(deepObject.fn1()).resolves.toBe(expected1); + expect(fn1).toBeCalledTimes(1); + await expect(deepObject.path.to.fn2()).resolves.toBe(expected2); + expect(fn2).toBeCalledTimes(1); + }); +}); diff --git a/packages/proxy-service/src/defineServiceProxy.ts b/packages/proxy-service/src/defineServiceProxy.ts new file mode 100644 index 0000000..a1b04c1 --- /dev/null +++ b/packages/proxy-service/src/defineServiceProxy.ts @@ -0,0 +1,89 @@ +import { isBackground } from './isBackground'; +import { ProxyService, ProxyServiceConfig, Service } from './types'; +import { defineExtensionMessaging, ProtocolWithReturn } from '@webext-core/messaging'; +import get from 'get-value'; + +/** + * Utility for creating a service whose functions are executed in the background script regardless + * of the JS context they are called from. + * + * @param name A unique name for the service. Used to identify which service is being executed. + * @param config An object that allows configuration of the underlying messaging service + * + * @returns + * - `registerService`: Used to register your service in the background. Requires an `init()` callback used to create the actual service object. + * - `getService`: Used to get an instance of the service anywhere in the extension. + */ +export function defineServiceProxy( + name: string, + config?: ProxyServiceConfig, +): [ + registerService: ( + init: (...args: any[]) => TService | Promise, + ...args: any[] + ) => Promise, + getService: () => ProxyService, +] { + let service: TService | undefined; + + const messageKey = `proxy-service.${name}`; + const { onMessage, sendMessage } = defineExtensionMessaging<{ + [key: string]: ProtocolWithReturn<{ path?: string; args: any[] }, any>; + }>(config); + + /** + * Create and returns a "deep" proxy. Every property that is accessed returns another proxy, and + * when a function is called at any depth (0 to infinity), a message is sent to the background. + */ + function createProxy(path?: string): ProxyService { + const wrapped = (() => {}) as ProxyService; + const proxy = new Proxy(wrapped, { + // Executed when the object is called as a function + async apply(_target, _thisArg, args) { + const res = await sendMessage(messageKey, { + path, + args: args, + }); + return res; + }, + + // Executed when accessing a property on an object + get(target, propertyName, receiver) { + if (propertyName === '__proxy' || typeof propertyName === 'symbol') { + return Reflect.get(target, propertyName, receiver); + } + return createProxy(path == null ? propertyName : `${path}.${propertyName}`); + }, + }); + // @ts-expect-error: Adding a hidden property + proxy.__proxy = true; + return proxy; + } + + return [ + async function registerService( + init: (...args: TArgs) => TService | Promise, + ...args: TArgs + ): Promise { + service = await init(...args); + onMessage(messageKey, ({ data }) => { + const method = data.path == null ? service : get(service ?? {}, data.path); + if (method) return Promise.resolve(method.bind(service)(...data.args)); + }); + return service; + }, + + function getService() { + // Create proxy for non-background + if (!isBackground()) return createProxy(); + + // Register the service if it hasn't been registered yet + if (service == null) { + throw Error( + `Failed to get an instance of ${name}: in background, but registerService has not been called. Did you forget to call registerService?`, + ); + } + return service as ProxyService; + }, + ]; +} diff --git a/packages/proxy-service/src/index.ts b/packages/proxy-service/src/index.ts index 7c2634f..5b83e01 100644 --- a/packages/proxy-service/src/index.ts +++ b/packages/proxy-service/src/index.ts @@ -1,3 +1,4 @@ -export { defineProxyService, defineShakableProxyService } from './defineProxyService'; +export { defineProxyService } from './defineProxyService'; +export { defineServiceProxy } from './defineServiceProxy'; export { flattenPromise } from './flattenPromise'; export type { ProxyServiceConfig, ProxyService, DeepAsync } from './types';