@powerhousedao/reactor-api 6.2.3-dev.3 → 6.2.3-dev.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{adapter-gateway-apollo-Cn9E96GF.mjs → adapter-gateway-apollo-CxJNBVyD.mjs} +6 -7
- package/dist/adapter-gateway-apollo-CxJNBVyD.mjs.map +1 -0
- package/dist/{adapter-gateway-apollo-C_RdohOv.mjs → adapter-gateway-apollo-DowrX6E_.mjs} +3 -3
- package/dist/{adapter-gateway-mercurius-CjaUcMgX.mjs → adapter-gateway-mercurius-CZVy88Za.mjs} +6 -5
- package/dist/adapter-gateway-mercurius-CZVy88Za.mjs.map +1 -0
- package/dist/{adapter-gateway-stitching-HmWjRMhm.mjs → adapter-gateway-stitching-CaZjvRzx.mjs} +7 -8
- package/dist/adapter-gateway-stitching-CaZjvRzx.mjs.map +1 -0
- package/dist/index.d.mts +24 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +86 -31
- package/dist/index.mjs.map +1 -1
- package/dist/src/packages/vite-loader.d.mts.map +1 -1
- package/dist/src/packages/vite-loader.mjs +5 -5
- package/dist/src/packages/vite-loader.mjs.map +1 -1
- package/package.json +14 -14
- package/dist/adapter-gateway-apollo-Cn9E96GF.mjs.map +0 -1
- package/dist/adapter-gateway-mercurius-CjaUcMgX.mjs.map +0 -1
- package/dist/adapter-gateway-stitching-HmWjRMhm.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-loader.d.mts","names":[],"sources":["../../../src/packages/vite-loader.mts"],"mappings":";;;;;;;iBAqBgB,gBAAA,CAAiB,MAAA,EAAQ,OAAA,EAAS,MAAA,YAAW,MAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"vite-loader.d.mts","names":[],"sources":["../../../src/packages/vite-loader.mts"],"mappings":";;;;;;;iBAqBgB,gBAAA,CAAiB,MAAA,EAAQ,OAAA,EAAS,MAAA,YAAW,MAAA;AAAA,cA2BhD,iBAAA,YAA6B,0BAAA;EAAA;mBACvB,MAAA;EAAA,iBAEA,IAAA;EAAA,SAER,IAAA;EAAA,OAEF,KAAA,CAAM,IAAA,EAAM,aAAA,GAAa,iBAAA;cAIpB,IAAA,EAAM,aAAA;EAAA,QAIV,qBAAA;EAAA,QAIA,gBAAA;EAAA,QAIA,iBAAA;EAID,kBAAA,CAAmB,UAAA,UAAoB,SAAA,aAAiB,OAAA,CAAA,mBAAA;EA2CzD,oBAAA,CACJ,UAAA,WACC,OAAA,CAAQ,eAAA;EA+BL,aAAA,CAAc,UAAA,WAAqB,OAAA,CAAQ,aAAA;EA4B3C,cAAA,CACJ,UAAA,WACC,OAAA,CAAQ,uBAAA;EA+BX,sBAAA,CACE,UAAA,UACA,OAAA,GAAU,cAAA,EAAgB,mBAAA,aAC1B,OAAA,GAAU,oBAAA;EAwBZ,iBAAA,CACE,UAAA,UACA,OAAA,GAAU,SAAA,EAAW,aAAA,aACrB,OAAA,GAAU,oBAAA;EAuBZ,kBAAA,CACE,UAAA,UACA,OAAA,GAAU,UAAA,EAAY,uBAAA,kBACtB,OAAA,GAAU,oBAAA;AAAA;AAAA,iBAwBQ,eAAA,CAAgB,IAAA,UAAc,MAAA,GAAS,MAAA,GAAM,OAAA,CAAA,aAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="9da64ff1-d15d-5b85-94b1-f1b0dad67551")}catch(e){}}();
|
|
3
3
|
import { a as isSubgraphClass, c as isSubpath, o as debounce, s as extractUpgradeManifests } from "../../utils-XWVecaNn.mjs";
|
|
4
4
|
import { childLogger } from "document-model";
|
|
5
5
|
import path from "node:path";
|
|
@@ -9,9 +9,9 @@ import { createLogger, createServer } from "vite";
|
|
|
9
9
|
//#region src/packages/vite-loader.mts
|
|
10
10
|
function createViteLogger(logger, prefix = "") {
|
|
11
11
|
const customLogger = createLogger("info", { prefix });
|
|
12
|
-
customLogger.info = logger.info;
|
|
13
|
-
customLogger.warn = logger.warn;
|
|
14
|
-
customLogger.error = logger.error;
|
|
12
|
+
customLogger.info = (msg) => logger.info("@line", msg);
|
|
13
|
+
customLogger.warn = (msg) => logger.warn("@line", msg);
|
|
14
|
+
customLogger.error = (msg, options) => options?.error ? logger.error("@line", msg, options.error) : logger.error("@line", msg);
|
|
15
15
|
return customLogger;
|
|
16
16
|
}
|
|
17
17
|
var VitePackageLoader = class VitePackageLoader {
|
|
@@ -167,4 +167,4 @@ async function startViteServer(root, logger) {
|
|
|
167
167
|
export { VitePackageLoader, createViteLogger, startViteServer };
|
|
168
168
|
|
|
169
169
|
//# sourceMappingURL=vite-loader.mjs.map
|
|
170
|
-
//# debugId=
|
|
170
|
+
//# debugId=9da64ff1-d15d-5b85-94b1-f1b0dad67551
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-loader.mjs","sources":["../../../src/packages/vite-loader.mts"],"sourcesContent":["import { viteCommonjs } from \"@originjs/vite-plugin-commonjs\";\nimport type {\n ProcessorFactoryBuilder,\n SubgraphClass,\n} from \"@powerhousedao/reactor-api\";\nimport type {\n DocumentModelModule,\n UpgradeManifest,\n} from \"@powerhousedao/shared/document-model\";\nimport { childLogger, type ILogger } from \"document-model\";\nimport path from \"node:path\";\nimport { readPackage } from \"read-pkg\";\nimport type { Logger, PluginOption, ViteDevServer } from \"vite\";\nimport { createLogger, createServer } from \"vite\";\nimport { isSubgraphClass } from \"../graphql/utils.js\";\nimport type {\n ISubscribablePackageLoader,\n ISubscriptionOptions,\n} from \"./types.js\";\nimport { debounce, extractUpgradeManifests, isSubpath } from \"./util.js\";\n\nexport function createViteLogger(logger: ILogger, prefix = \"\") {\n const customLogger = createLogger(\"info\", {\n prefix,\n });\n customLogger.info = logger.info;\n customLogger.warn = logger.warn;\n customLogger.error = logger.error;\n return customLogger;\n}\n\nexport class VitePackageLoader implements ISubscribablePackageLoader {\n private readonly logger = childLogger([\"reactor-api\", \"vite-loader\"]);\n\n private readonly vite: ViteDevServer;\n\n readonly name = \"VitePackageLoader\";\n\n static build(vite: ViteDevServer) {\n return new VitePackageLoader(vite);\n }\n\n constructor(vite: ViteDevServer) {\n this.vite = vite;\n }\n\n private getDocumentModelsPath(identifier: string): string {\n return path.posix.join(identifier, \"./document-models\");\n }\n\n private getSubgraphsPath(identifier: string): string {\n return path.posix.join(identifier, \"./subgraphs\");\n }\n\n private getProcessorsPath(identifier: string): string {\n return path.posix.join(identifier, \"./processors\");\n }\n\n public loadDocumentModels(identifier: string, immediate = false) {\n return this.#loadDocumentModelsWithDebounce(immediate, identifier);\n }\n\n #loadDocumentModelsWithDebounce = debounce(\n this.#loadDocumentModels.bind(this),\n 500,\n );\n\n async #loadDocumentModels(\n identifier: string,\n ): Promise<DocumentModelModule[]> {\n const fullPath = this.getDocumentModelsPath(identifier);\n this.logger.debug(\"Loading document models from\", fullPath);\n\n try {\n const localDMs = (await this.vite.ssrLoadModule(fullPath)) as Record<\n string,\n DocumentModelModule\n >;\n\n const exports = Object.values(localDMs);\n\n // duck type\n const documentModels: DocumentModelModule[] = [];\n for (const dm of exports) {\n if (dm.documentModel) {\n documentModels.push(dm);\n }\n }\n\n this.logger.verbose(\n ` ➜ Loaded ${documentModels.length} Document Models from: ${identifier}`,\n );\n\n return documentModels;\n } catch (e) {\n this.logger.debug(` ➜ No Document Models found for: ${identifier}`, e);\n }\n\n return [];\n }\n\n async loadUpgradeManifests(\n identifier: string,\n ): Promise<UpgradeManifest<readonly number[]>[]> {\n // Projects generated before the aggregate index re-exported the\n // manifests only expose them at document-models/upgrade-manifests, so\n // try both without requiring a regeneration.\n const candidatePaths = [\n this.getDocumentModelsPath(identifier),\n path.posix.join(this.getDocumentModelsPath(identifier), \"upgrade-manifests\"),\n ];\n for (const fullPath of candidatePaths) {\n try {\n const namespace = (await this.vite.ssrLoadModule(fullPath)) as Record<\n string,\n unknown\n >;\n const manifests = extractUpgradeManifests(namespace);\n if (manifests.length > 0) {\n this.logger.verbose(\n ` ➜ Loaded ${manifests.length} Upgrade Manifests from: ${identifier}`,\n );\n return manifests;\n }\n } catch (e) {\n this.logger.debug(\n ` ➜ No Upgrade Manifests found at ${fullPath} for: ${identifier}`,\n e,\n );\n }\n }\n return [];\n }\n\n async loadSubgraphs(identifier: string): Promise<SubgraphClass[]> {\n const fullPath = this.getSubgraphsPath(identifier);\n\n this.logger.verbose(\"Loading subgraphs from\", fullPath);\n\n let localSubgraphs: Record<string, Record<string, SubgraphClass>> = {};\n try {\n localSubgraphs = await this.vite.ssrLoadModule(fullPath);\n } catch (e) {\n this.logger.debug(` ➜ No Subgraphs found for: ${identifier}`, e);\n return [];\n }\n\n const subgraphs: SubgraphClass[] = [];\n for (const [name, subgraph] of Object.entries(localSubgraphs)) {\n const SubgraphClass = subgraph[name];\n if (isSubgraphClass(SubgraphClass)) {\n subgraphs.push(SubgraphClass);\n }\n }\n\n this.logger.debug(\n ` ➜ Loaded ${subgraphs.length} Subgraphs from: ${identifier}`,\n );\n\n return subgraphs;\n }\n\n async loadProcessors(\n identifier: string,\n ): Promise<ProcessorFactoryBuilder | null> {\n const fullPath = this.getProcessorsPath(identifier);\n\n this.logger.verbose(\"Loading processors from\", fullPath);\n\n try {\n const pkgModule = await this.vite.ssrLoadModule(fullPath);\n\n const factory = (\n pkgModule as Record<string, ProcessorFactoryBuilder | undefined>\n )?.processorFactory;\n\n if (factory && typeof factory === \"function\") {\n this.logger.verbose(\n ` ➜ Loaded Processor Factory from: ${identifier}`,\n );\n return factory;\n }\n } catch (e) {\n this.logger.debug(\n ` ➜ No Processor Factory found for: ${identifier}`,\n e,\n );\n }\n\n this.logger.verbose(` ➜ No Processor Factory found for: ${identifier}`);\n\n // return empty processor factory\n return null;\n }\n\n onDocumentModelsChange(\n identifier: string,\n handler: (documentModels: DocumentModelModule[]) => void,\n options?: ISubscriptionOptions,\n ): () => void {\n const listener = async (changedPath: string) => {\n const documentModelsPath = this.getDocumentModelsPath(identifier);\n if (isSubpath(documentModelsPath, changedPath)) {\n const documentModels = await this.loadDocumentModels(identifier);\n handler(documentModels);\n }\n };\n\n // \"change\" alone misses files that are created or deleted: a removed\n // document-models/ entry would never report an empty result, and the\n // package's registered models would leak.\n this.vite.watcher.on(\"change\", listener);\n this.vite.watcher.on(\"add\", listener);\n this.vite.watcher.on(\"unlink\", listener);\n\n return () => {\n this.vite.watcher.off(\"change\", listener);\n this.vite.watcher.off(\"add\", listener);\n this.vite.watcher.off(\"unlink\", listener);\n };\n }\n\n onSubgraphsChange(\n identifier: string,\n handler: (subgraphs: SubgraphClass[]) => void,\n options?: ISubscriptionOptions,\n ): () => void {\n const subgraphsPath = this.getSubgraphsPath(identifier);\n const listener = async (changedPath: string) => {\n if (isSubpath(subgraphsPath, changedPath)) {\n const subgraphs = await this.loadSubgraphs(identifier);\n handler(subgraphs);\n }\n };\n // \"change\" alone misses files that are created or deleted: a removed\n // subgraphs/ entry would never report an empty result, and the\n // package's registered subgraphs would leak.\n this.vite.watcher.on(\"change\", listener);\n this.vite.watcher.on(\"add\", listener);\n this.vite.watcher.on(\"unlink\", listener);\n\n return () => {\n this.vite.watcher.off(\"change\", listener);\n this.vite.watcher.off(\"add\", listener);\n this.vite.watcher.off(\"unlink\", listener);\n };\n }\n\n onProcessorsChange(\n identifier: string,\n handler: (processors: ProcessorFactoryBuilder | null) => void,\n options?: ISubscriptionOptions,\n ): () => void {\n const processorsPath = this.getProcessorsPath(identifier);\n const listener = async (changedPath: string) => {\n if (isSubpath(processorsPath, changedPath)) {\n const processors = await this.loadProcessors(identifier);\n handler(processors);\n }\n };\n // \"change\" alone misses files that are created or deleted: a removed\n // processors/ entry would never report an empty result, and the\n // package's registered processor factories would leak.\n this.vite.watcher.on(\"change\", listener);\n this.vite.watcher.on(\"add\", listener);\n this.vite.watcher.on(\"unlink\", listener);\n\n return () => {\n this.vite.watcher.off(\"change\", listener);\n this.vite.watcher.off(\"add\", listener);\n this.vite.watcher.off(\"unlink\", listener);\n };\n }\n}\n\nexport async function startViteServer(root: string, logger?: Logger) {\n const packageJson = await readPackage({ cwd: root });\n\n const vite = await createServer({\n root,\n configFile: false,\n logger,\n server: { middlewareMode: true, watch: { ignored: [\"**/.ph/**\"] } },\n appType: \"custom\",\n build: {\n rollupOptions: {\n input: [],\n },\n },\n resolve: {\n tsconfigPaths: true,\n alias: {\n [packageJson.name]: root,\n },\n },\n plugins: [\n // cast: the plugin ships types built against an older vite, and the\n // mismatched Plugin type crashes tsc 6 during assignability checking\n viteCommonjs() as PluginOption,\n {\n name: \"suppress-hmr\",\n handleHotUpdate() {\n return []; // return empty array to suppress server refresh\n },\n },\n ],\n });\n\n return vite;\n}\n"],"names":["#loadDocumentModelsWithDebounce","#loadDocumentModels"],"mappings":"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","debug_id":"e3971ec2-a824-5da6-9a2a-805e72db81bf"}
|
|
1
|
+
{"version":3,"file":"vite-loader.mjs","sources":["../../../src/packages/vite-loader.mts"],"sourcesContent":["import { viteCommonjs } from \"@originjs/vite-plugin-commonjs\";\nimport type {\n ProcessorFactoryBuilder,\n SubgraphClass,\n} from \"@powerhousedao/reactor-api\";\nimport type {\n DocumentModelModule,\n UpgradeManifest,\n} from \"@powerhousedao/shared/document-model\";\nimport { childLogger, type ILogger } from \"document-model\";\nimport path from \"node:path\";\nimport { readPackage } from \"read-pkg\";\nimport type { Logger, PluginOption, ViteDevServer } from \"vite\";\nimport { createLogger, createServer } from \"vite\";\nimport { isSubgraphClass } from \"../graphql/utils.js\";\nimport type {\n ISubscribablePackageLoader,\n ISubscriptionOptions,\n} from \"./types.js\";\nimport { debounce, extractUpgradeManifests, isSubpath } from \"./util.js\";\n\nexport function createViteLogger(logger: ILogger, prefix = \"\") {\n const customLogger = createLogger(\"info\", {\n prefix,\n });\n // Wrapped rather than assigned: the logger methods are bound to their own\n // instance, and re-homing them onto Vite's logger object made every Vite\n // log line throw.\n //\n // Vite's text goes through as a replacement, never as the format string: it\n // is somebody else's prose, not a template. `ILogger` substitutes `@token`,\n // and Vite log lines are full of npm scopes, so `pre-transforming\n // @powerhousedao/design-system` came out as `pre-transforming\n // null/design-system`. Substituting into `@line` instead emits it verbatim.\n //\n // Vite's second argument is dropped for the same reason. It is `LogOptions`\n // -- `{ clear, timestamp }` -- and forwarding it made it the replacement for\n // whatever `@token` the line happened to contain, or got appended as JSON.\n // Only `error` keeps it, where it carries the error itself.\n customLogger.info = (msg) => logger.info(\"@line\", msg);\n customLogger.warn = (msg) => logger.warn(\"@line\", msg);\n customLogger.error = (msg, options) =>\n options?.error\n ? logger.error(\"@line\", msg, options.error)\n : logger.error(\"@line\", msg);\n return customLogger;\n}\n\nexport class VitePackageLoader implements ISubscribablePackageLoader {\n private readonly logger = childLogger([\"reactor-api\", \"vite-loader\"]);\n\n private readonly vite: ViteDevServer;\n\n readonly name = \"VitePackageLoader\";\n\n static build(vite: ViteDevServer) {\n return new VitePackageLoader(vite);\n }\n\n constructor(vite: ViteDevServer) {\n this.vite = vite;\n }\n\n private getDocumentModelsPath(identifier: string): string {\n return path.posix.join(identifier, \"./document-models\");\n }\n\n private getSubgraphsPath(identifier: string): string {\n return path.posix.join(identifier, \"./subgraphs\");\n }\n\n private getProcessorsPath(identifier: string): string {\n return path.posix.join(identifier, \"./processors\");\n }\n\n public loadDocumentModels(identifier: string, immediate = false) {\n return this.#loadDocumentModelsWithDebounce(immediate, identifier);\n }\n\n #loadDocumentModelsWithDebounce = debounce(\n this.#loadDocumentModels.bind(this),\n 500,\n );\n\n async #loadDocumentModels(\n identifier: string,\n ): Promise<DocumentModelModule[]> {\n const fullPath = this.getDocumentModelsPath(identifier);\n this.logger.debug(\"Loading document models from\", fullPath);\n\n try {\n const localDMs = (await this.vite.ssrLoadModule(fullPath)) as Record<\n string,\n DocumentModelModule\n >;\n\n const exports = Object.values(localDMs);\n\n // duck type\n const documentModels: DocumentModelModule[] = [];\n for (const dm of exports) {\n if (dm.documentModel) {\n documentModels.push(dm);\n }\n }\n\n this.logger.verbose(\n ` ➜ Loaded ${documentModels.length} Document Models from: ${identifier}`,\n );\n\n return documentModels;\n } catch (e) {\n this.logger.debug(` ➜ No Document Models found for: ${identifier}`, e);\n }\n\n return [];\n }\n\n async loadUpgradeManifests(\n identifier: string,\n ): Promise<UpgradeManifest<readonly number[]>[]> {\n // Projects generated before the aggregate index re-exported the\n // manifests only expose them at document-models/upgrade-manifests, so\n // try both without requiring a regeneration.\n const candidatePaths = [\n this.getDocumentModelsPath(identifier),\n path.posix.join(this.getDocumentModelsPath(identifier), \"upgrade-manifests\"),\n ];\n for (const fullPath of candidatePaths) {\n try {\n const namespace = (await this.vite.ssrLoadModule(fullPath)) as Record<\n string,\n unknown\n >;\n const manifests = extractUpgradeManifests(namespace);\n if (manifests.length > 0) {\n this.logger.verbose(\n ` ➜ Loaded ${manifests.length} Upgrade Manifests from: ${identifier}`,\n );\n return manifests;\n }\n } catch (e) {\n this.logger.debug(\n ` ➜ No Upgrade Manifests found at ${fullPath} for: ${identifier}`,\n e,\n );\n }\n }\n return [];\n }\n\n async loadSubgraphs(identifier: string): Promise<SubgraphClass[]> {\n const fullPath = this.getSubgraphsPath(identifier);\n\n this.logger.verbose(\"Loading subgraphs from\", fullPath);\n\n let localSubgraphs: Record<string, Record<string, SubgraphClass>> = {};\n try {\n localSubgraphs = await this.vite.ssrLoadModule(fullPath);\n } catch (e) {\n this.logger.debug(` ➜ No Subgraphs found for: ${identifier}`, e);\n return [];\n }\n\n const subgraphs: SubgraphClass[] = [];\n for (const [name, subgraph] of Object.entries(localSubgraphs)) {\n const SubgraphClass = subgraph[name];\n if (isSubgraphClass(SubgraphClass)) {\n subgraphs.push(SubgraphClass);\n }\n }\n\n this.logger.debug(\n ` ➜ Loaded ${subgraphs.length} Subgraphs from: ${identifier}`,\n );\n\n return subgraphs;\n }\n\n async loadProcessors(\n identifier: string,\n ): Promise<ProcessorFactoryBuilder | null> {\n const fullPath = this.getProcessorsPath(identifier);\n\n this.logger.verbose(\"Loading processors from\", fullPath);\n\n try {\n const pkgModule = await this.vite.ssrLoadModule(fullPath);\n\n const factory = (\n pkgModule as Record<string, ProcessorFactoryBuilder | undefined>\n )?.processorFactory;\n\n if (factory && typeof factory === \"function\") {\n this.logger.verbose(\n ` ➜ Loaded Processor Factory from: ${identifier}`,\n );\n return factory;\n }\n } catch (e) {\n this.logger.debug(\n ` ➜ No Processor Factory found for: ${identifier}`,\n e,\n );\n }\n\n this.logger.verbose(` ➜ No Processor Factory found for: ${identifier}`);\n\n // return empty processor factory\n return null;\n }\n\n onDocumentModelsChange(\n identifier: string,\n handler: (documentModels: DocumentModelModule[]) => void,\n options?: ISubscriptionOptions,\n ): () => void {\n const listener = async (changedPath: string) => {\n const documentModelsPath = this.getDocumentModelsPath(identifier);\n if (isSubpath(documentModelsPath, changedPath)) {\n const documentModels = await this.loadDocumentModels(identifier);\n handler(documentModels);\n }\n };\n\n // \"change\" alone misses files that are created or deleted: a removed\n // document-models/ entry would never report an empty result, and the\n // package's registered models would leak.\n this.vite.watcher.on(\"change\", listener);\n this.vite.watcher.on(\"add\", listener);\n this.vite.watcher.on(\"unlink\", listener);\n\n return () => {\n this.vite.watcher.off(\"change\", listener);\n this.vite.watcher.off(\"add\", listener);\n this.vite.watcher.off(\"unlink\", listener);\n };\n }\n\n onSubgraphsChange(\n identifier: string,\n handler: (subgraphs: SubgraphClass[]) => void,\n options?: ISubscriptionOptions,\n ): () => void {\n const subgraphsPath = this.getSubgraphsPath(identifier);\n const listener = async (changedPath: string) => {\n if (isSubpath(subgraphsPath, changedPath)) {\n const subgraphs = await this.loadSubgraphs(identifier);\n handler(subgraphs);\n }\n };\n // \"change\" alone misses files that are created or deleted: a removed\n // subgraphs/ entry would never report an empty result, and the\n // package's registered subgraphs would leak.\n this.vite.watcher.on(\"change\", listener);\n this.vite.watcher.on(\"add\", listener);\n this.vite.watcher.on(\"unlink\", listener);\n\n return () => {\n this.vite.watcher.off(\"change\", listener);\n this.vite.watcher.off(\"add\", listener);\n this.vite.watcher.off(\"unlink\", listener);\n };\n }\n\n onProcessorsChange(\n identifier: string,\n handler: (processors: ProcessorFactoryBuilder | null) => void,\n options?: ISubscriptionOptions,\n ): () => void {\n const processorsPath = this.getProcessorsPath(identifier);\n const listener = async (changedPath: string) => {\n if (isSubpath(processorsPath, changedPath)) {\n const processors = await this.loadProcessors(identifier);\n handler(processors);\n }\n };\n // \"change\" alone misses files that are created or deleted: a removed\n // processors/ entry would never report an empty result, and the\n // package's registered processor factories would leak.\n this.vite.watcher.on(\"change\", listener);\n this.vite.watcher.on(\"add\", listener);\n this.vite.watcher.on(\"unlink\", listener);\n\n return () => {\n this.vite.watcher.off(\"change\", listener);\n this.vite.watcher.off(\"add\", listener);\n this.vite.watcher.off(\"unlink\", listener);\n };\n }\n}\n\nexport async function startViteServer(root: string, logger?: Logger) {\n const packageJson = await readPackage({ cwd: root });\n\n const vite = await createServer({\n root,\n configFile: false,\n logger,\n server: { middlewareMode: true, watch: { ignored: [\"**/.ph/**\"] } },\n appType: \"custom\",\n build: {\n rollupOptions: {\n input: [],\n },\n },\n resolve: {\n tsconfigPaths: true,\n alias: {\n [packageJson.name]: root,\n },\n },\n plugins: [\n // cast: the plugin ships types built against an older vite, and the\n // mismatched Plugin type crashes tsc 6 during assignability checking\n viteCommonjs() as PluginOption,\n {\n name: \"suppress-hmr\",\n handleHotUpdate() {\n return []; // return empty array to suppress server refresh\n },\n },\n ],\n });\n\n return vite;\n}\n"],"names":["#loadDocumentModelsWithDebounce","#loadDocumentModels"],"mappings":"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","debug_id":"9da64ff1-d15d-5b85-94b1-f1b0dad67551"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powerhousedao/reactor-api",
|
|
3
|
-
"version": "6.2.3-dev.
|
|
3
|
+
"version": "6.2.3-dev.4",
|
|
4
4
|
"description": "GraphQL API layer for the Powerhouse reactor  auto-generated subgraphs per document model plus the core reactor subgraph for drive and document management.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -59,24 +59,24 @@
|
|
|
59
59
|
"@graphql-tools/schema": "10.0.31",
|
|
60
60
|
"@graphql-tools/utils": "11.0.0",
|
|
61
61
|
"@originjs/vite-plugin-commonjs": "^1.0.3",
|
|
62
|
-
"@powerhousedao/analytics-engine-core": "6.2.3-dev.
|
|
63
|
-
"@powerhousedao/analytics-engine-graphql": "6.2.3-dev.
|
|
64
|
-
"@powerhousedao/analytics-engine-pg": "6.2.3-dev.
|
|
65
|
-
"@powerhousedao/config": "6.2.3-dev.
|
|
62
|
+
"@powerhousedao/analytics-engine-core": "6.2.3-dev.4",
|
|
63
|
+
"@powerhousedao/analytics-engine-graphql": "6.2.3-dev.4",
|
|
64
|
+
"@powerhousedao/analytics-engine-pg": "6.2.3-dev.4",
|
|
65
|
+
"@powerhousedao/config": "6.2.3-dev.4",
|
|
66
66
|
"@powerhousedao/document-engineering": "1.40.5",
|
|
67
|
-
"@powerhousedao/pglite-fs": "6.2.3-dev.
|
|
68
|
-
"@powerhousedao/reactor": "6.2.3-dev.
|
|
69
|
-
"@powerhousedao/reactor-attachments": "6.2.3-dev.
|
|
70
|
-
"@powerhousedao/reactor-drive": "6.2.3-dev.
|
|
71
|
-
"@powerhousedao/reactor-group": "6.2.3-dev.
|
|
72
|
-
"@powerhousedao/reactor-mcp": "6.2.3-dev.
|
|
73
|
-
"@powerhousedao/shared": "6.2.3-dev.
|
|
74
|
-
"@renown/sdk": "6.2.3-dev.
|
|
67
|
+
"@powerhousedao/pglite-fs": "6.2.3-dev.4",
|
|
68
|
+
"@powerhousedao/reactor": "6.2.3-dev.4",
|
|
69
|
+
"@powerhousedao/reactor-attachments": "6.2.3-dev.4",
|
|
70
|
+
"@powerhousedao/reactor-drive": "6.2.3-dev.4",
|
|
71
|
+
"@powerhousedao/reactor-group": "6.2.3-dev.4",
|
|
72
|
+
"@powerhousedao/reactor-mcp": "6.2.3-dev.4",
|
|
73
|
+
"@powerhousedao/shared": "6.2.3-dev.4",
|
|
74
|
+
"@renown/sdk": "6.2.3-dev.4",
|
|
75
75
|
"body-parser": "^1.20.3",
|
|
76
76
|
"change-case": "5.4.4",
|
|
77
77
|
"cors": "^2.8.5",
|
|
78
78
|
"devcert": "^1.2.2",
|
|
79
|
-
"document-model": "6.2.3-dev.
|
|
79
|
+
"document-model": "6.2.3-dev.4",
|
|
80
80
|
"dotenv": "^16.4.5",
|
|
81
81
|
"express": "4.21.1",
|
|
82
82
|
"graphql-sse": "2.6.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adapter-gateway-apollo-Cn9E96GF.mjs","sources":["../src/graphql/gateway/adapter-gateway-apollo.ts"],"sourcesContent":["import type {\n GetDataSourceFunction,\n GraphQLDataSourceProcessOptions,\n ServiceDefinition,\n SubgraphHealthCheckFunction,\n SupergraphSdlUpdateFunction,\n} from \"@apollo/gateway\";\nimport {\n ApolloGateway,\n LocalCompose,\n RemoteGraphQLDataSource,\n} from \"@apollo/gateway\";\nimport { ApolloServer, HeaderMap } from \"@apollo/server\";\nimport { ApolloServerPluginInlineTraceDisabled } from \"@apollo/server/plugin/disabled\";\nimport { ApolloServerPluginDrainHttpServer } from \"@apollo/server/plugin/drainHttpServer\";\nimport { ApolloServerPluginLandingPageLocalDefault } from \"@apollo/server/plugin/landingPage/default\";\nimport { buildSubgraphSchema } from \"@apollo/subgraph\";\nimport type { ILogger } from \"document-model\";\nimport type { GraphQLSchema } from \"graphql\";\nimport type http from \"node:http\";\nimport type { WebSocketServer } from \"ws\";\nimport type { Context } from \"../types.js\";\nimport { useServer } from \"../websocket.js\";\nimport type {\n FetchHandler,\n GatewayContextFactory,\n IGatewayAdapter,\n SubgraphDefinition,\n WsContextFactory,\n WsDisposer,\n} from \"./types.js\";\n\n/**\n * Drop subgraphs whose typeDefs cannot be built into a valid subgraph schema in\n * isolation — e.g. a duplicate type definition within a single subgraph (Sentry\n * #917) — so one broken subgraph is excluded instead of failing the build for\n * everyone. Each excluded subgraph is logged; the rest are composed.\n *\n * Scope: this only catches per-subgraph build failures. Errors that surface only\n * when subgraphs are composed together (cross-subgraph type or `@key` conflicts)\n * are still thrown by `LocalCompose.initialize()` and are NOT handled here.\n */\nexport function filterComposableSubgraphs(\n serviceList: ServiceDefinition[],\n logger?: Pick<ILogger, \"error\">,\n): ServiceDefinition[] {\n return serviceList.filter((service) => {\n try {\n // Array form: @apollo/subgraph 2.15 dropped the bare-module overload.\n buildSubgraphSchema([{ typeDefs: service.typeDefs }]);\n return true;\n } catch (error) {\n logger?.error(\n `Excluding subgraph \"${service.name}\" from supergraph composition: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n return false;\n }\n });\n}\n\n// Forwards the incoming authorization header to federated subgraph requests.\nclass AuthenticatedDataSource extends RemoteGraphQLDataSource {\n constructor(\n config?: ConstructorParameters<typeof RemoteGraphQLDataSource>[0],\n ) {\n // Node's fetch retires a pooled connection before the subgraph server's advertised keep-alive\n // timeout; Apollo's default make-fetch-happen agent holds it until the server closes it under us.\n super({\n fetcher: fetch as RemoteGraphQLDataSource[\"fetcher\"],\n ...config,\n });\n }\n\n willSendRequest(options: GraphQLDataSourceProcessOptions) {\n const { authorization } = options.context.headers as {\n authorization: string;\n };\n if (authorization && options?.request.http) {\n options.request.http.headers.set(\"authorization\", authorization);\n }\n }\n}\n\nexport class ApolloGatewayAdapter implements IGatewayAdapter<Context> {\n readonly #logger: ILogger;\n readonly #servers: ApolloServer<Context>[] = [];\n\n #supergraphServer: ApolloServer<Context> | null = null;\n #gatewayOptions: {\n update: SupergraphSdlUpdateFunction;\n healthCheck: SubgraphHealthCheckFunction;\n getDataSource: GetDataSourceFunction;\n } | null = null;\n #getSubgraphs: (() => SubgraphDefinition[]) | null = null;\n\n constructor(logger: ILogger) {\n this.#logger = logger;\n }\n\n async start(_httpServer: http.Server): Promise<void> {\n // Per-subgraph Apollo servers start lazily in createHandler.\n // Nothing to do here.\n }\n\n async createHandler(\n schema: GraphQLSchema,\n contextFactory: GatewayContextFactory<Context>,\n ): Promise<FetchHandler> {\n const server = new ApolloServer<Context>({\n schema,\n logger: this.#logger,\n introspection: true,\n // Each ApolloServer otherwise registers its own SIGINT/SIGTERM handler\n // that re-emits the signal via process.kill after server.stop() resolves.\n // With many subgraph servers that re-emit lands while the reactor's\n // graceful-shutdown chain is mid-flight, looking like a \"second SIGINT\"\n // to the reactor and aborting cleanup. The reactor drives our shutdown\n // end-to-end (see ReactorBuilder.attachSignalHandlers), so opt out.\n stopOnTerminationSignals: false,\n plugins: [\n ApolloServerPluginInlineTraceDisabled(),\n ApolloServerPluginLandingPageLocalDefault(),\n ],\n });\n await server.start();\n this.#servers.push(server);\n return createApolloFetchHandler(server, contextFactory);\n }\n\n async createSupergraphHandler(\n getSubgraphs: () => SubgraphDefinition[],\n httpServer: http.Server,\n contextFactory: GatewayContextFactory<Context>,\n ): Promise<FetchHandler> {\n if (this.#supergraphServer) {\n throw new Error(\"Supergraph server is already running\");\n }\n\n this.#getSubgraphs = getSubgraphs;\n\n const gateway = new ApolloGateway({\n supergraphSdl: async (options) => {\n this.#gatewayOptions = options;\n return await this.#buildSupergraphSdl();\n },\n buildService: (serviceConfig) =>\n new AuthenticatedDataSource(serviceConfig),\n });\n\n this.#supergraphServer = new ApolloServer<Context>({\n gateway,\n logger: this.#logger,\n introspection: true,\n stopOnTerminationSignals: false,\n plugins: [\n ApolloServerPluginDrainHttpServer({ httpServer }),\n ApolloServerPluginInlineTraceDisabled(),\n ApolloServerPluginLandingPageLocalDefault(),\n ],\n });\n\n await this.#supergraphServer.start();\n return createApolloFetchHandler(this.#supergraphServer, contextFactory);\n }\n\n async updateSupergraph(): Promise<void> {\n if (!this.#gatewayOptions || !this.#getSubgraphs) {\n // Not yet initialized - no-op.\n return;\n }\n const { supergraphSdl } = await this.#buildSupergraphSdl();\n this.#gatewayOptions.update(supergraphSdl);\n }\n\n async #buildSupergraphSdl() {\n if (!this.#gatewayOptions || !this.#getSubgraphs) {\n throw new Error(\"Gateway is not ready\");\n }\n const serviceList: ServiceDefinition[] = this.#getSubgraphs().map((s) => ({\n name: s.name,\n typeDefs: s.typeDefs,\n url: s.url,\n }));\n const composableServiceList = filterComposableSubgraphs(\n serviceList,\n this.#logger,\n );\n const localCompose = new LocalCompose({\n localServiceList: composableServiceList,\n });\n return localCompose.initialize(this.#gatewayOptions);\n }\n\n attachWebSocket(\n wsServer: WebSocketServer,\n schema: GraphQLSchema,\n contextFactory: WsContextFactory<Context>,\n ): WsDisposer {\n return useServer(\n {\n schema,\n context: async (ctx: {\n connectionParams?: Record<string, unknown>;\n }) => {\n const connectionParams = (ctx.connectionParams ?? {}) as Record<\n string,\n unknown\n >;\n return contextFactory(connectionParams);\n },\n },\n wsServer,\n );\n }\n\n async stop(): Promise<void> {\n await Promise.all(this.#servers.map((s) => s.stop()));\n this.#servers.length = 0;\n\n if (this.#supergraphServer) {\n await this.#supergraphServer.stop();\n this.#supergraphServer = null;\n }\n this.#gatewayOptions = null;\n this.#getSubgraphs = null;\n }\n}\n\n/**\n * Wrap an existing ApolloServer as a Fetch API handler.\n * Does not manage server lifecycle; caller is responsible for start/stop.\n */\nexport function createApolloFetchHandler(\n server: ApolloServer<Context>,\n contextFactory: GatewayContextFactory<Context>,\n): FetchHandler {\n return async (request: Request): Promise<Response> => {\n const url = new URL(request.url);\n const headers = new HeaderMap();\n request.headers.forEach((value, key) => headers.set(key, value));\n\n let body: unknown = undefined;\n if (request.method !== \"GET\" && request.method !== \"HEAD\") {\n try {\n body = (await request.json()) as unknown;\n } catch {\n // body may be empty for some requests\n }\n }\n\n const result = await server.executeHTTPGraphQLRequest({\n httpGraphQLRequest: {\n method: request.method.toUpperCase(),\n headers,\n search: url.search,\n body,\n },\n context: () => contextFactory(request),\n });\n\n const responseHeaders = new Headers();\n for (const [key, value] of result.headers) {\n responseHeaders.set(key, value);\n }\n\n let responseBody: string;\n if (result.body.kind === \"complete\") {\n responseBody = result.body.string;\n } else {\n const chunks: string[] = [];\n for await (const chunk of result.body.asyncIterator) {\n chunks.push(chunk);\n }\n responseBody = chunks.join(\"\");\n }\n\n return new Response(responseBody, {\n status: result.status ?? 200,\n headers: responseHeaders,\n });\n };\n}\n"],"names":["#logger","#servers","#supergraphServer","#getSubgraphs","#gatewayOptions","#buildSupergraphSdl"],"mappings":"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","debug_id":"982fddf9-a797-565f-bc37-ed1c52432374"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adapter-gateway-mercurius-CjaUcMgX.mjs","sources":["../src/graphql/gateway/adapter-gateway-mercurius.ts"],"sourcesContent":["import type { MercuriusGatewayOptions } from \"@mercuriusjs/gateway\";\nimport mercuriusGateway from \"@mercuriusjs/gateway\";\nimport Fastify from \"fastify\";\nimport type {\n FastifyInstance,\n FastifyPluginCallback,\n FastifyReply,\n FastifyRequest,\n} from \"fastify\";\nimport mercurius from \"mercurius\";\nimport type { MercuriusOptions } from \"mercurius\";\nimport type { ILogger } from \"document-model\";\nimport type { GraphQLSchema } from \"graphql\";\nimport type http from \"node:http\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { WebSocketServer } from \"ws\";\nimport type { Context } from \"../types.js\";\nimport { useServer } from \"../websocket.js\";\nimport type {\n FetchHandler,\n GatewayContextFactory,\n IGatewayAdapter,\n SubgraphDefinition,\n WsContextFactory,\n WsDisposer,\n} from \"./types.js\";\n\n/**\n * Threads the original Fetch API Request through Mercurius's internal\n * fastify.inject() call so that contextFactory (which uses the auth WeakMap\n * from auth-middleware.ts) receives the same Request object that auth\n * middleware populated before calling the handler.\n */\nconst requestAls = new AsyncLocalStorage<Request>();\n\n// @mercuriusjs/gateway exports a plain `(instance, opts) => void` rather than\n// a typed FastifyPluginCallback — cast once here.\n// The gateway plugin's accepted options are the intersection of the base\n// MercuriusOptions and MercuriusGatewayOptions (mirroring the unexported\n// MercuriusFederationOptions type in the package).\ntype GatewayPluginOptions = MercuriusOptions & MercuriusGatewayOptions;\nconst mercuriusGatewayPlugin =\n mercuriusGateway as unknown as FastifyPluginCallback<GatewayPluginOptions>;\n\nexport class MercuriusGatewayAdapter implements IGatewayAdapter<Context> {\n readonly #logger: ILogger;\n readonly #subgraphApps: FastifyInstance[] = [];\n\n #supergraphApp: FastifyInstance | null = null;\n #getSubgraphs: (() => SubgraphDefinition[]) | null = null;\n #supergraphContextFactory: GatewayContextFactory<Context> | null = null;\n\n constructor(logger: ILogger) {\n this.#logger = logger;\n }\n\n async start(_httpServer: http.Server): Promise<void> {\n // Mercurius instances are started lazily in createHandler /\n // createSupergraphHandler — nothing to do here.\n }\n\n async createHandler(\n schema: GraphQLSchema,\n contextFactory: GatewayContextFactory<Context>,\n ): Promise<FetchHandler> {\n const app = await buildMercuriusApp(schema, contextFactory, this.#logger);\n this.#subgraphApps.push(app);\n return buildFetchHandler(app);\n }\n\n async createSupergraphHandler(\n getSubgraphs: () => SubgraphDefinition[],\n _httpServer: http.Server,\n contextFactory: GatewayContextFactory<Context>,\n ): Promise<FetchHandler> {\n if (this.#supergraphApp) {\n throw new Error(\"Supergraph is already running\");\n }\n this.#getSubgraphs = getSubgraphs;\n this.#supergraphContextFactory = contextFactory;\n this.#supergraphApp = await buildGatewayApp(\n getSubgraphs(),\n contextFactory,\n this.#logger,\n );\n\n // Capture `this` so the returned handler always delegates to the *current*\n // #supergraphApp, allowing updateSupergraph() to swap it atomically.\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const adapter = this;\n return (request: Request): Promise<Response> => {\n if (!adapter.#supergraphApp) {\n return Promise.resolve(\n new Response(\"Gateway not ready\", { status: 503 }),\n );\n }\n return requestAls.run(request, () =>\n injectRequest(adapter.#supergraphApp!, request),\n );\n };\n }\n\n async updateSupergraph(): Promise<void> {\n if (!this.#getSubgraphs || !this.#supergraphContextFactory) return;\n const newApp = await buildGatewayApp(\n this.#getSubgraphs(),\n this.#supergraphContextFactory,\n this.#logger,\n );\n const oldApp = this.#supergraphApp;\n // Swap atomically — in-flight requests on the old app finish normally.\n this.#supergraphApp = newApp;\n if (oldApp) await oldApp.close();\n }\n\n attachWebSocket(\n wsServer: WebSocketServer,\n schema: GraphQLSchema,\n contextFactory: WsContextFactory<Context>,\n ): WsDisposer {\n // Use graphql-ws directly; Mercurius's own subscription transport is\n // Fastify-specific and not applicable here.\n return useServer(\n {\n schema,\n context: async (ctx: { connectionParams?: Record<string, unknown> }) =>\n contextFactory(ctx.connectionParams ?? {}),\n },\n wsServer,\n );\n }\n\n async stop(): Promise<void> {\n await Promise.all(this.#subgraphApps.map((app) => app.close()));\n this.#subgraphApps.length = 0;\n if (this.#supergraphApp) {\n await this.#supergraphApp.close();\n this.#supergraphApp = null;\n }\n this.#getSubgraphs = null;\n this.#supergraphContextFactory = null;\n }\n}\n\n// ── Fastify instance factories ────────────────────────────────────────────────\n\nfunction makeContextFn(\n contextFactory: GatewayContextFactory<Context>,\n logger: ILogger,\n) {\n return (_req: FastifyRequest, _reply: FastifyReply) => {\n const request = requestAls.getStore();\n if (!request) {\n logger.error(\"[mercurius] No Fetch Request in AsyncLocalStorage\");\n throw new Error(\"No Fetch Request in AsyncLocalStorage\");\n }\n return contextFactory(request);\n };\n}\n\nasync function buildMercuriusApp(\n schema: GraphQLSchema,\n contextFactory: GatewayContextFactory<Context>,\n logger: ILogger,\n): Promise<FastifyInstance> {\n const app = Fastify({ logger: false });\n\n await app.register(mercurius, {\n schema,\n graphiql: false,\n context: makeContextFn(contextFactory, logger),\n // Override _Service.sdl to rewrite \"type Query/Mutation/Subscription {\"\n // as \"extend type … {\" so that @mercuriusjs/gateway v5 (which follows the\n // Federation v1 convention of using extensionTypeMap) correctly maps root\n // operation fields to this service during query planning.\n resolvers: {\n _Service: {\n sdl: (parent: { sdl?: string }) =>\n (parent.sdl ?? \"\").replace(\n /\\btype\\s+(Query|Mutation|Subscription)\\s*\\{/g,\n \"extend type $1 {\",\n ),\n },\n },\n } satisfies MercuriusOptions);\n\n await app.ready();\n return app;\n}\n\n/**\n * Builds a Mercurius federation gateway that composes the given subgraph\n * services. Each service URL must be reachable so that the gateway can fetch\n * its SDL via `_service { sdl }` (Apollo Federation protocol).\n */\nasync function buildGatewayApp(\n subgraphs: SubgraphDefinition[],\n contextFactory: GatewayContextFactory<Context>,\n logger: ILogger,\n): Promise<FastifyInstance> {\n const app = Fastify({ logger: false });\n\n await app.register(mercuriusGatewayPlugin, {\n gateway: {\n services: subgraphs.map((s) => ({ name: s.name, url: s.url })),\n },\n graphiql: false,\n context: makeContextFn(contextFactory, logger),\n });\n\n await app.ready();\n return app;\n}\n\n// ── Fetch API bridge ──────────────────────────────────────────────────────────\n\nfunction buildFetchHandler(app: FastifyInstance): FetchHandler {\n return (request: Request): Promise<Response> =>\n requestAls.run(request, () => injectRequest(app, request));\n}\n\nasync function injectRequest(\n app: FastifyInstance,\n request: Request,\n): Promise<Response> {\n const body =\n request.method !== \"GET\" && request.method !== \"HEAD\"\n ? await request.text()\n : undefined;\n\n const headers: Record<string, string> = {};\n request.headers.forEach((value, key) => {\n headers[key] = value;\n });\n\n const response = await app.inject({\n method: request.method as\n | \"DELETE\"\n | \"GET\"\n | \"HEAD\"\n | \"OPTIONS\"\n | \"PATCH\"\n | \"POST\"\n | \"PUT\",\n url: \"/graphql\",\n headers,\n payload: body,\n });\n\n const responseHeaders: Record<string, string> = {};\n for (const [key, value] of Object.entries(response.headers)) {\n if (value !== undefined) responseHeaders[key] = String(value);\n }\n\n return new Response(response.payload, {\n status: response.statusCode,\n headers: responseHeaders,\n });\n}\n"],"names":["#logger","#subgraphApps","#supergraphApp","#getSubgraphs","#supergraphContextFactory"],"mappings":"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","debug_id":"930607cc-96ff-5d76-a4b6-95e39b5963d1"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adapter-gateway-stitching-HmWjRMhm.mjs","sources":["../src/graphql/gateway/adapter-gateway-stitching.ts"],"sourcesContent":["import { ApolloServer } from \"@apollo/server\";\nimport { ApolloServerPluginInlineTraceDisabled } from \"@apollo/server/plugin/disabled\";\nimport { ApolloServerPluginLandingPageLocalDefault } from \"@apollo/server/plugin/landingPage/default\";\nimport { mergeResolvers, mergeTypeDefs } from \"@graphql-tools/merge\";\nimport { makeExecutableSchema } from \"@graphql-tools/schema\";\nimport type { IResolvers } from \"@graphql-tools/utils\";\nimport {\n buildASTSchema,\n type DefinitionNode,\n type DocumentNode,\n isTypeDefinitionNode,\n isTypeExtensionNode,\n Kind,\n parse,\n print,\n type GraphQLNamedType,\n type GraphQLSchema,\n type TypeDefinitionNode,\n validateSchema,\n} from \"graphql\";\nimport type http from \"node:http\";\nimport type { WebSocketServer } from \"ws\";\nimport type { ILogger } from \"document-model\";\nimport type { Context } from \"../types.js\";\nimport { useServer } from \"../websocket.js\";\nimport { createApolloFetchHandler } from \"./adapter-gateway-apollo.js\";\nimport type {\n FetchHandler,\n GatewayContextFactory,\n IGatewayAdapter,\n SubgraphDefinition,\n WsContextFactory,\n WsDisposer,\n} from \"./types.js\";\n\n/**\n * How to resolve two subgraphs that define the same field with incompatible\n * types (a name clash, the #1565 scenario).\n *\n * - `\"last\"` (default): the later-registered subgraph's field definition wins.\n * - `\"first\"`: the earlier-registered subgraph's field definition wins.\n *\n * Every conflict is logged either way; unlike federation composition, the\n * supergraph is still built. The policy applies to field type clashes only:\n * a type-KIND clash (the same type name declared as an object by one subgraph\n * and as an enum/input/interface/union by another) is resolved by\n * `mergeTypeDefs` itself, which always keeps the last declaration. Those are\n * detected separately and reported through the same channel so they are\n * logged rather than dropped in silence.\n */\nexport type StitchConflictPolicy = \"first\" | \"last\";\n\nexport type StitchingGatewayOptions = {\n onFieldTypeConflict?: StitchConflictPolicy;\n};\n\n/** Root operation types, which a subgraph may extend without defining. */\nconst ROOT_TYPE_NAMES = [\"Query\", \"Mutation\", \"Subscription\"];\n\n/**\n * A placeholder declaration for a type name a subgraph borrows from another\n * subgraph. Same kind as the real declaration, so the borrowing subgraph's\n * SDL validates the same way it does in the merged supergraph:\n *\n * - scalar/enum/input/object: a minimal declaration of that kind.\n * - interface: the real declaration, because a subgraph that implements the\n * interface has to satisfy its field set.\n * - union: a self-contained union over one placeholder member, so nothing the\n * real declaration references has to be resolvable here.\n */\nfunction stubDeclaration(\n name: string,\n owner: TypeDefinitionNode | undefined,\n): string {\n switch (owner?.kind) {\n case Kind.SCALAR_TYPE_DEFINITION:\n return `scalar ${name}`;\n case Kind.ENUM_TYPE_DEFINITION:\n return `enum ${name} { _STUB }`;\n case Kind.INPUT_OBJECT_TYPE_DEFINITION:\n return `input ${name} { _stub: Boolean }`;\n case Kind.INTERFACE_TYPE_DEFINITION:\n return print(owner);\n case Kind.UNION_TYPE_DEFINITION:\n return `type ${name}_Stub { _stub: Boolean } union ${name} = ${name}_Stub`;\n default:\n return `type ${name} { _stub: Boolean }`;\n }\n}\n\n/**\n * Drops subgraphs whose own typeDefs cannot be built into a valid schema, so\n * one malformed subgraph is excluded instead of failing the whole supergraph\n * build (which, since GraphQLManager.init() does not guard the supergraph\n * gateway, would be a boot failure). Each excluded subgraph is logged; the\n * rest are merged. This is the stitching counterpart of the federation path's\n * `filterComposableSubgraphs`.\n *\n * A stitching subgraph is not self-contained the way a federation subgraph is:\n * it may extend a root type it never defines (`analytics` only does\n * `extend type Query`) and reference types another subgraph owns (in raw form\n * `analytics` uses `DateTime`, declared by `auth`/`reactor`/`packages`).\n * Building it alone would therefore reject perfectly good subgraphs. So the isolation build adds\n * a placeholder declaration for every type name declared by some *other*\n * subgraph in the set, plus the root types, plus every directive definition in\n * the set. What is left to fail is the subgraph's own SDL: a dangling type\n * reference no subgraph declares, a duplicated field, an invalid implements\n * clause.\n *\n * Scope: like the federation filter, this only catches per-subgraph failures.\n * Errors that appear only once subgraphs are merged (a field type or type kind\n * clash) are reported by `mergeSubgraphTypeDefs`, not here.\n */\nexport function filterBuildableSubgraphs(\n subgraphs: SubgraphDefinition[],\n logger?: Pick<ILogger, \"error\">,\n): SubgraphDefinition[] {\n // First declaration of each type name across the whole set, for stub kinds.\n const owners = new Map<string, TypeDefinitionNode>();\n const directiveDefs = new Map<string, DefinitionNode>();\n for (const subgraph of subgraphs) {\n for (const def of subgraph.typeDefs.definitions) {\n if (isTypeDefinitionNode(def) && !owners.has(def.name.value)) {\n owners.set(def.name.value, def);\n } else if (\n def.kind === Kind.DIRECTIVE_DEFINITION &&\n !directiveDefs.has(def.name.value)\n ) {\n directiveDefs.set(def.name.value, def);\n }\n }\n }\n\n return subgraphs.filter((subgraph) => {\n const own = new Set<string>();\n const ownDirectives = new Set<string>();\n for (const def of subgraph.typeDefs.definitions) {\n if (isTypeDefinitionNode(def)) {\n own.add(def.name.value);\n } else if (def.kind === Kind.DIRECTIVE_DEFINITION) {\n ownDirectives.add(def.name.value);\n }\n }\n\n const stubs: string[] = [];\n for (const name of new Set([...owners.keys(), ...ROOT_TYPE_NAMES])) {\n if (!own.has(name)) {\n stubs.push(stubDeclaration(name, owners.get(name)));\n }\n }\n for (const [name, def] of directiveDefs) {\n if (!ownDirectives.has(name)) {\n stubs.push(print(def));\n }\n }\n\n try {\n // Merge the same way the supergraph does, so a subgraph that declares a\n // type twice within itself is normalized here too, then build and\n // validate: buildASTSchema asserts the SDL, validateSchema the result.\n const documents =\n stubs.length > 0\n ? [subgraph.typeDefs, parse(stubs.join(\"\\n\"))]\n : [subgraph.typeDefs];\n const merged = mergeTypeDefs(documents, { useSchemaDefinition: false });\n const errors = validateSchema(buildASTSchema(merged));\n if (errors.length > 0) {\n throw new Error(errors.map((error) => error.message).join(\"; \"));\n }\n return true;\n } catch (error) {\n logger?.error(\n `Stitching gateway: excluding subgraph \"${subgraph.name}\" from the supergraph: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n return false;\n }\n });\n}\n\n/**\n * The SDL keyword for a type definition or extension node, or undefined for a\n * node that does not declare a named type (schema definitions, directive\n * definitions, executable definitions). Extensions map to the same keyword as\n * their definition: `extend type Query` and `type Query` are the same kind.\n */\nfunction typeKeyword(def: DefinitionNode): string | undefined {\n switch (def.kind) {\n case Kind.OBJECT_TYPE_DEFINITION:\n case Kind.OBJECT_TYPE_EXTENSION:\n return \"type\";\n case Kind.INTERFACE_TYPE_DEFINITION:\n case Kind.INTERFACE_TYPE_EXTENSION:\n return \"interface\";\n case Kind.UNION_TYPE_DEFINITION:\n case Kind.UNION_TYPE_EXTENSION:\n return \"union\";\n case Kind.ENUM_TYPE_DEFINITION:\n case Kind.ENUM_TYPE_EXTENSION:\n return \"enum\";\n case Kind.INPUT_OBJECT_TYPE_DEFINITION:\n case Kind.INPUT_OBJECT_TYPE_EXTENSION:\n return \"input\";\n case Kind.SCALAR_TYPE_DEFINITION:\n case Kind.SCALAR_TYPE_EXTENSION:\n return \"scalar\";\n default:\n return undefined;\n }\n}\n\n/**\n * Finds type names that two subgraphs declare with different kinds (object vs\n * enum, input, interface or union). `mergeTypeDefs` does not call\n * `onFieldTypeConflict` for these - it keeps the last declaration and drops\n * the other subgraph's type entirely, with no diagnostic - so they are\n * scanned for before the merge and reported alongside field conflicts.\n */\nfunction scanTypeKindClashes(subgraphs: SubgraphDefinition[]): string[] {\n const clashes: string[] = [];\n const declaredBy = new Map<string, { keyword: string; subgraph: string }>();\n for (const subgraph of subgraphs) {\n for (const def of subgraph.typeDefs.definitions) {\n if (!isTypeDefinitionNode(def) && !isTypeExtensionNode(def)) {\n continue;\n }\n const keyword = typeKeyword(def);\n if (keyword === undefined) {\n continue;\n }\n const name = def.name.value;\n const previous = declaredBy.get(name);\n if (previous === undefined) {\n declaredBy.set(name, { keyword, subgraph: subgraph.name });\n continue;\n }\n if (previous.keyword === keyword) {\n continue;\n }\n clashes.push(\n `type kind clash on ${name}: declared as ${previous.keyword} by ` +\n `subgraph \"${previous.subgraph}\" and as ${keyword} by subgraph ` +\n `\"${subgraph.name}\"; mergeTypeDefs keeps the last declaration ` +\n `(${keyword}) and drops the other, whatever the conflict policy`,\n );\n // Track what the merge actually keeps, so a third declaration is\n // compared against the surviving kind.\n declaredBy.set(name, { keyword, subgraph: subgraph.name });\n }\n }\n return clashes;\n}\n\n/**\n * Merges all subgraph type definitions into one schema, applying the field\n * conflict policy. Exported so tests and the benchmark can exercise the merge\n * without a full adapter.\n */\nexport function mergeSubgraphTypeDefs(\n subgraphs: SubgraphDefinition[],\n policy: StitchConflictPolicy,\n): { typeDefs: DocumentNode; conflicts: string[] } {\n const conflicts: string[] = scanTypeKindClashes(subgraphs);\n const typeDefs = mergeTypeDefs(\n subgraphs.map((s) => s.typeDefs),\n {\n // Never emit a `schema { ... }` block: the merged root types are\n // determined by whichever subgraphs define Query/Mutation/Subscription.\n useSchemaDefinition: false,\n onFieldTypeConflict: (existing, other, type) => {\n // Identical definitions are normal stitching (shared types across\n // subgraphs); only differing definitions are conflicts.\n if (print(existing) === print(other)) {\n return existing;\n }\n const winner = policy === \"first\" ? existing : other;\n const loser = policy === \"first\" ? other : existing;\n conflicts.push(\n `field type clash on ${type.name.value}.${existing.name.value}: kept ` +\n `${print(winner.type)} (${\n policy === \"first\" ? \"first\" : \"last\"\n } subgraph), dropped ${print(loser.type)}`,\n );\n return winner;\n },\n },\n );\n return { typeDefs, conflicts };\n}\n\n/**\n * Merges the subgraph resolver maps in the order the conflict policy implies.\n * `mergeResolvers` is unconditionally last-wins, so under `\"first\"` the array\n * is reversed: the first-registered subgraph's resolver ends up applied last\n * and wins, matching the field type the merged schema advertises. Without\n * this the schema would advertise one subgraph's type while another\n * subgraph's resolver ran.\n */\nfunction mergeSubgraphResolvers(\n subgraphs: SubgraphDefinition[],\n policy: StitchConflictPolicy,\n): IResolvers {\n const ordered = policy === \"first\" ? [...subgraphs].reverse() : subgraphs;\n return mergeResolvers(\n ordered.map((s) => s.resolvers as IResolvers | undefined),\n );\n}\n\n/**\n * Drops resolver entries that have no matching type or field in the merged\n * schema. Document-model subgraphs generate resolver entries for operations\n * their SDL does not declare (the federation runtime silently ignores those);\n * makeExecutableSchema rejects them, so they are filtered before the build.\n */\nfunction filterResolversToSchema(\n typeMap: Record<string, GraphQLNamedType | undefined>,\n resolvers: Record<string, unknown>,\n logger?: Pick<ILogger, \"debug\">,\n): Record<string, unknown> {\n const filtered: Record<string, unknown> = {};\n for (const [typeName, entry] of Object.entries(resolvers)) {\n const type = typeMap[typeName];\n if (type === undefined) {\n // Type not part of the merged schema.\n logger?.debug(\n `Stitching gateway: dropped resolvers for type \"${typeName}\": the merged schema has no such type`,\n );\n continue;\n }\n const fields =\n type instanceof Object && \"getFields\" in type\n ? (type as { getFields(): Record<string, unknown> }).getFields()\n : undefined;\n if (fields === undefined) {\n // Scalar, enum, or union resolver: keep as-is.\n filtered[typeName] = entry;\n continue;\n }\n if (entry === null || typeof entry !== \"object\") {\n // Not a resolver map: nothing to keep.\n logger?.debug(\n `Stitching gateway: dropped resolver entry for type \"${typeName}\": expected a field map, got ${entry === null ? \"null\" : typeof entry}`,\n );\n continue;\n }\n const map = entry as { [key: string]: unknown };\n const kept: Record<string, unknown> = {};\n const dropped: string[] = [];\n for (const [key, value] of Object.entries(map)) {\n if (key === \"__resolveReference\" || fields[key] !== undefined) {\n kept[key] = value;\n } else {\n dropped.push(key);\n }\n }\n if (dropped.length > 0) {\n logger?.debug(\n `Stitching gateway: dropped resolvers ${dropped\n .map((field) => `${typeName}.${field}`)\n .join(\", \")}: the merged schema declares no such field(s)`,\n );\n }\n if (Object.keys(kept).length > 0) {\n filtered[typeName] = kept;\n }\n }\n return filtered;\n}\n\n/**\n * Builds the executable supergraph schema from merged type definitions and\n * resolvers (shared by the adapter and the pure merge helper).\n */\nfunction buildMergedSchema(\n typeDefs: DocumentNode,\n resolvers: IResolvers,\n logger?: Pick<ILogger, \"debug\">,\n): GraphQLSchema {\n // A type-only build to get the merged type map; assumeValid skips SDL\n // validation, which makeExecutableSchema performs on the real build.\n const typeMap = buildASTSchema(typeDefs, { assumeValid: true }).getTypeMap();\n // The filter works on the raw resolver shape; the result is a valid\n // IResolvers because it only removes entries from one.\n const filtered = filterResolversToSchema(\n typeMap,\n resolvers as Record<string, unknown>,\n logger,\n );\n return makeExecutableSchema({ typeDefs, resolvers: filtered as IResolvers });\n}\n\n/**\n * Merges multiple subgraphs into a single in-process executable schema.\n * This is the \"Guild\" (graphql-tools) composition path: instead of federation\n * (which hard-fails on cross-subgraph type conflicts and executes subgraph\n * fields over loopback HTTP), the type definitions are merged with an\n * explicit conflict policy and the resolvers run in-process.\n */\nexport function mergeSubgraphSchemas(\n subgraphs: SubgraphDefinition[],\n policy: StitchConflictPolicy,\n): GraphQLSchema {\n if (subgraphs.length === 0) {\n throw new Error(\"Cannot merge zero subgraphs\");\n }\n const { typeDefs } = mergeSubgraphTypeDefs(subgraphs, policy);\n const resolvers = mergeSubgraphResolvers(subgraphs, policy);\n return buildMergedSchema(typeDefs, resolvers);\n}\n\n/**\n * A stitching gateway adapter: the supergraph is one merged schema executed\n * in-process. Subgraph routes (`/graphql/<name>`) are served exactly like the\n * Apollo adapter, so direct subgraph access is unchanged.\n *\n * Note: unlike the Apollo adapter, the supergraph ApolloServer is NOT given\n * ApolloServerPluginDrainHttpServer. The plugin closes the (shared) HTTP\n * server on stop, which would kill every mounted subgraph route when\n * updateSupergraph() swaps the supergraph server. The shared server is drained\n * explicitly in stop() instead.\n */\nexport class StitchingGatewayAdapter implements IGatewayAdapter<Context> {\n readonly #logger: ILogger;\n readonly #policy: StitchConflictPolicy;\n\n readonly #servers: ApolloServer<Context>[] = [];\n #supergraphServer: ApolloServer<Context> | null = null;\n #handler: FetchHandler | null = null;\n #httpServer: http.Server | null = null;\n #getSubgraphs: (() => SubgraphDefinition[]) | null = null;\n #contextFactory: GatewayContextFactory<Context> | null = null;\n\n constructor(logger: ILogger, options: StitchingGatewayOptions = {}) {\n this.#logger = logger;\n this.#policy = options.onFieldTypeConflict ?? \"last\";\n }\n\n async start(_httpServer: http.Server): Promise<void> {\n // Per-subgraph Apollo servers start lazily in createHandler.\n // Nothing to do here.\n }\n\n async createHandler(\n schema: GraphQLSchema,\n contextFactory: GatewayContextFactory<Context>,\n ): Promise<FetchHandler> {\n const server = await this.#makeServer(schema);\n this.#servers.push(server);\n return createApolloFetchHandler(server, contextFactory);\n }\n\n async createSupergraphHandler(\n getSubgraphs: () => SubgraphDefinition[],\n httpServer: http.Server,\n contextFactory: GatewayContextFactory<Context>,\n ): Promise<FetchHandler> {\n if (this.#supergraphServer) {\n throw new Error(\"Supergraph server is already running\");\n }\n\n this.#getSubgraphs = getSubgraphs;\n this.#httpServer = httpServer;\n this.#contextFactory = contextFactory;\n\n const server = await this.#buildSupergraphServer(getSubgraphs());\n return this.#installSupergraphServer(server);\n }\n\n async updateSupergraph(): Promise<void> {\n if (!this.#getSubgraphs || !this.#contextFactory) {\n // Not yet initialized - no-op.\n return;\n }\n const server = await this.#buildSupergraphServer(this.#getSubgraphs());\n const old = this.#supergraphServer;\n this.#installSupergraphServer(server);\n // The handler swap above is atomic: new requests use the new server,\n // in-flight requests on the old one finish normally.\n if (old) {\n await old.stop();\n }\n }\n\n attachWebSocket(\n wsServer: WebSocketServer,\n schema: GraphQLSchema,\n contextFactory: WsContextFactory<Context>,\n ): WsDisposer {\n return useServer(\n {\n schema,\n context: async (ctx: {\n connectionParams?: Record<string, unknown>;\n }) => {\n const connectionParams = (ctx.connectionParams ?? {}) as {\n [key: string]: unknown;\n };\n return contextFactory(connectionParams);\n },\n },\n wsServer,\n );\n }\n\n async stop(): Promise<void> {\n await Promise.all(this.#servers.map((s) => s.stop()));\n this.#servers.length = 0;\n\n if (this.#supergraphServer) {\n await this.#supergraphServer.stop();\n this.#supergraphServer = null;\n }\n this.#handler = null;\n // Same as the Apollo adapter: clearing these makes a later\n // updateSupergraph() a no-op instead of resurrecting a stopped adapter.\n this.#getSubgraphs = null;\n this.#contextFactory = null;\n\n // Drain the shared HTTP server ourselves (the Apollo adapter gets this\n // from ApolloServerPluginDrainHttpServer, which we cannot use here - see\n // class comment). Only close a server that is still accepting connections\n // so a later close by the owner is a no-op instead of an error.\n const httpServer = this.#httpServer;\n this.#httpServer = null;\n if (httpServer?.listening) {\n await new Promise<void>((resolve) => httpServer.close(() => resolve()));\n }\n }\n\n // ── internals ──────────────────────────────────────────────────────────────\n\n async #makeServer(schema: GraphQLSchema): Promise<ApolloServer<Context>> {\n const server = new ApolloServer<Context>({\n schema,\n logger: this.#logger,\n introspection: true,\n // Same rationale as the Apollo adapter: the reactor drives shutdown\n // end-to-end; per-subgraph servers must not re-emit SIGINT.\n stopOnTerminationSignals: false,\n plugins: [\n ApolloServerPluginInlineTraceDisabled(),\n ApolloServerPluginLandingPageLocalDefault(),\n ],\n });\n await server.start();\n return server;\n }\n\n async #buildSupergraphServer(\n all: SubgraphDefinition[],\n ): Promise<ApolloServer<Context>> {\n let subgraphs = filterBuildableSubgraphs(all, this.#logger);\n if (subgraphs.length === 0 && all.length > 0) {\n // Excluding every subgraph would trade one subgraph's error for a\n // supergraph with no root type at all; keep the original set so the\n // build fails with the underlying error instead.\n this.#logger.error(\n \"Stitching gateway: every subgraph failed its isolation build; merging the unfiltered set so the underlying error surfaces\",\n );\n subgraphs = all;\n }\n const { typeDefs, conflicts } = mergeSubgraphTypeDefs(\n subgraphs,\n this.#policy,\n );\n for (const conflict of conflicts) {\n this.#logger.warn(\n `Stitching gateway (policy \"${this.#policy}\"): ${conflict}`,\n );\n }\n if (conflicts.length > 0) {\n this.#logger.warn(\n `Stitching gateway: merged ${subgraphs.length} subgraphs with ${conflicts.length} schema conflict(s); each resolution is logged above`,\n );\n } else {\n this.#logger.debug(\n `Stitching gateway: merged ${subgraphs.length} subgraphs without conflicts`,\n );\n }\n const resolvers = mergeSubgraphResolvers(subgraphs, this.#policy);\n const schema = buildMergedSchema(typeDefs, resolvers, this.#logger);\n return this.#makeServer(schema);\n }\n\n #installSupergraphServer(server: ApolloServer<Context>): FetchHandler {\n if (this.#contextFactory === null) {\n throw new Error(\"Supergraph context factory not set\");\n }\n this.#supergraphServer = server;\n const handler = createApolloFetchHandler(server, this.#contextFactory);\n this.#handler = handler;\n // The returned handler always delegates to the *current* server so\n // updateSupergraph() swaps are picked up without re-mounting the route.\n return (request: Request) => this.#handler!(request);\n }\n}\n"],"names":["#logger","#policy","#servers","#makeServer","#supergraphServer","#getSubgraphs","#httpServer","#contextFactory","#buildSupergraphServer","#installSupergraphServer","#handler"],"mappings":"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","debug_id":"afa9b5b1-60a1-5855-ae7e-fa7bb34cef57"}
|