diff --git a/bun.lock b/bun.lock index 970e94e..1cb207e 100644 --- a/bun.lock +++ b/bun.lock @@ -6,7 +6,7 @@ "name": ".", "dependencies": { "@aklinker1/logger": "^1.0.6", - "@aklinker1/zero-ioc": "^1.5.1", + "@aklinker1/zero-ioc": "^1.6.0", "@aklinker1/zero-serialize-error": "^1.0.2", "@aklinker1/zeta": "^2.2.0", "dataloader": "^2.2.3", @@ -34,7 +34,7 @@ "@aklinker1/logger": ["@aklinker1/logger@1.0.6", "", {}, "sha512-EMlpsa3tBgxSAzXV+WgnUNkaCh3G1SvYkvDjHhG9pQcBG+YxUKXtIUFuazQbyotsH/cdRMG+RxI7GI8NCQ40OQ=="], - "@aklinker1/zero-ioc": ["@aklinker1/zero-ioc@1.5.1", "", {}, "sha512-PIv6SlAJFIfBA7nrUxBswsMsUHSjHK0DYMqSxj9pFItst6lwJYTP9XfTo7lY1f/swwzauieRG7YopAjd1rvQfw=="], + "@aklinker1/zero-ioc": ["@aklinker1/zero-ioc@1.6.0", "", {}, "sha512-xiTXd2aOHnxr/Jbjj1Aw5kRo5i1d5BA1tEhNXKnz0svAWeT+fpqDf+2ONDrtU6FhHKsd5qo3w9H0lGzjomgaNw=="], "@aklinker1/zero-serialize-error": ["@aklinker1/zero-serialize-error@1.0.2", "", {}, "sha512-hGVkgFqb8Zs80JJ7MOSCGQXH2SyWfwnJwOl8Qpp1lUdkp5T7GTf8QrAMib42Hnzx6HtnNYdmNaSSg4MQy+MDRQ=="], diff --git a/package.json b/package.json index 0e9a99e..5a1892a 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ }, "dependencies": { "@aklinker1/logger": "^1.0.6", - "@aklinker1/zero-ioc": "^1.5.1", + "@aklinker1/zero-ioc": "^1.6.0", "@aklinker1/zero-serialize-error": "^1.0.2", "@aklinker1/zeta": "^2.2.0", "dataloader": "^2.2.3", diff --git a/src/@types/gql-ctx.d.ts b/src/@types/gql-ctx.d.ts index 4775d85..6b8158c 100644 --- a/src/@types/gql-ctx.d.ts +++ b/src/@types/gql-ctx.d.ts @@ -1,5 +1,5 @@ declare namespace Gql { export type WxtQueueCtx = { - deps: import("../dependencies").Dependencies; + deps: import("../dependencies").RequestDependencies; }; } diff --git a/src/apis/graphql-apis.ts b/src/apis/graphql-apis.ts index d58eafd..4990a8c 100644 --- a/src/apis/graphql-apis.ts +++ b/src/apis/graphql-apis.ts @@ -6,6 +6,7 @@ import { version } from "../../package.json"; import PLAYGROUND_HTML_TEMPLATE from "../assets/playground.html" with { type: "text" }; import { OpenApiTag } from "../enums"; import { createGraphql } from "../graphql"; +import { contextPlugin } from "../plugins/context-plugin"; const PLAYGROUND_HTML = (PLAYGROUND_HTML_TEMPLATE as any as string).replace("{{VERSION}}", version); @@ -14,6 +15,7 @@ const graphql = createGraphql(); export const graphqlApis = createApp({ tags: [OpenApiTag.Graphql], }) + .use(contextPlugin) .post( "/api", { @@ -67,7 +69,7 @@ export const graphqlApis = createApp({ }, }), }, - ({ request, body }) => graphql.evaluateQuery(request.method, body) as any, + ({ request, body, deps }) => graphql.evaluateQuery(deps, request.method, body) as any, ) .get( "/playground", diff --git a/src/dependencies.ts b/src/dependencies.ts index d681ffc..6b4d3f7 100644 --- a/src/dependencies.ts +++ b/src/dependencies.ts @@ -1,10 +1,9 @@ -import { createIocContainer, transient } from "@aklinker1/zero-ioc"; +import { createIocContainer } from "@aklinker1/zero-ioc"; -import { ExtensionStoreName } from "./enums"; import { createChromeWebStore } from "./services/chrome-web-store"; import { createEdgeAddonStore } from "./services/edge-addon-store"; import { createEdgeApi } from "./services/edge-api"; -import type { ExtensionStores } from "./services/extension-stores"; +import { ExtensionStoreProvider } from "./services/extension-store-provider"; import { createFirefoxAddonStore } from "./services/firefox-addon-store"; import { createFirefoxApi } from "./services/firefox-api"; import { createInMemoryCache } from "./services/in-memory-cache"; @@ -21,23 +20,15 @@ export const container = createIocContainer() : createInMemoryCache, ) .register("edgeApi", createEdgeApi) - .register("firefoxApi", createFirefoxApi) - .register("chromeWebStore", transient(createChromeWebStore)) - .register("firefoxAddonStore", transient(createFirefoxAddonStore)) - .register("edgeAddonStore", transient(createEdgeAddonStore)) - .register( - "stores", - (deps) => - ({ - [ExtensionStoreName.ChromeWebStore]: deps.chromeWebStore, - [ExtensionStoreName.FirefoxAddonStore]: deps.firefoxAddonStore, - [ExtensionStoreName.EdgeAddonStore]: deps.edgeAddonStore, - - // Deprecated, but staying around for a while. - [ExtensionStoreName.ChromeExtensions]: deps.chromeWebStore, - [ExtensionStoreName.FirefoxExtensions]: deps.firefoxAddonStore, - [ExtensionStoreName.EdgeExtensions]: deps.edgeAddonStore, - }) satisfies ExtensionStores, - ); + .register("firefoxApi", createFirefoxApi); export type Dependencies = typeof container.registrations; + +export const requestScope = container + .scope<{}>() + .register("chromeWebStore", createChromeWebStore) + .register("firefoxAddonStore", createFirefoxAddonStore) + .register("edgeAddonStore", createEdgeAddonStore) + .register("stores", ExtensionStoreProvider); + +export type RequestDependencies = ReturnType["registrations"]; diff --git a/src/graphql/index.ts b/src/graphql/index.ts index 5c961a4..c953265 100644 --- a/src/graphql/index.ts +++ b/src/graphql/index.ts @@ -2,7 +2,7 @@ import { createLogger } from "@aklinker1/logger"; import { buildSchema, graphql } from "graphql"; import gqlSchema from "../assets/schema.gql" with { type: "text" }; -import { container } from "../dependencies"; +import { type RequestDependencies } from "../dependencies"; import { rootResolver } from "./resolvers"; const logger = createLogger("gql"); @@ -12,7 +12,7 @@ export function createGraphql() { let increment = 0; - const evaluateQuery = async (method: string, body: GraphQLParams) => { + const evaluateQuery = async (deps: RequestDependencies, method: string, body: GraphQLParams) => { const id = ++increment; const { operationName = "Unknown", query, variables } = body; @@ -21,7 +21,7 @@ export function createGraphql() { logger.debug("Running query", { id, method, operationName }); const ctx: Gql.WxtQueueCtx = { - deps: container.registrations, + deps, }; const response = await graphql({ diff --git a/src/plugins/context-plugin.ts b/src/plugins/context-plugin.ts index 68e5413..0d12ea6 100644 --- a/src/plugins/context-plugin.ts +++ b/src/plugins/context-plugin.ts @@ -1,5 +1,7 @@ import { createApp } from "@aklinker1/zeta"; -import { container } from "../dependencies"; +import { requestScope } from "../dependencies"; -export const contextPlugin = createApp().decorate({ deps: container.registrations }).export(); +export const contextPlugin = createApp() + .onTransform(() => ({ deps: requestScope({}).registrations })) + .export(); diff --git a/src/services/extension-store-provider.ts b/src/services/extension-store-provider.ts new file mode 100644 index 0000000..0de5768 --- /dev/null +++ b/src/services/extension-store-provider.ts @@ -0,0 +1,33 @@ +import { ExtensionStoreName } from "../enums"; +import type { ExtensionStore } from "./extension-store"; + +export class ExtensionStoreProvider { + constructor( + readonly deps: { + chromeWebStore: ExtensionStore; + firefoxAddonStore: ExtensionStore; + edgeAddonStore: ExtensionStore; + }, + ) {} + + get [ExtensionStoreName.ChromeWebStore]() { + return this.deps.chromeWebStore; + } + get [ExtensionStoreName.ChromeExtensions]() { + return this.deps.chromeWebStore; + } + + get [ExtensionStoreName.FirefoxAddonStore]() { + return this.deps.firefoxAddonStore; + } + get [ExtensionStoreName.FirefoxExtensions]() { + return this.deps.firefoxAddonStore; + } + + get [ExtensionStoreName.EdgeAddonStore]() { + return this.deps.edgeAddonStore; + } + get [ExtensionStoreName.EdgeExtensions]() { + return this.deps.edgeAddonStore; + } +} diff --git a/src/services/extension-stores.ts b/src/services/extension-stores.ts deleted file mode 100644 index 8ddcf3e..0000000 --- a/src/services/extension-stores.ts +++ /dev/null @@ -1,4 +0,0 @@ -import type { ExtensionStoreName } from "../enums"; -import type { ExtensionStore } from "./extension-store"; - -export type ExtensionStores = Record>;