@powerhousedao/reactor-api 6.0.0-dev.11 → 6.0.0-dev.111

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.
Files changed (352) hide show
  1. package/README.md +6 -0
  2. package/dist/codegen.js +1 -1
  3. package/dist/codegen.js.map +1 -1
  4. package/dist/index.d.ts +4 -2
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +4 -2
  7. package/dist/index.js.map +1 -1
  8. package/dist/src/config.d.ts +1 -2
  9. package/dist/src/config.d.ts.map +1 -1
  10. package/dist/src/config.js +1 -5
  11. package/dist/src/config.js.map +1 -1
  12. package/dist/src/dev.d.ts +2 -0
  13. package/dist/src/dev.d.ts.map +1 -0
  14. package/dist/src/dev.js +51 -0
  15. package/dist/src/dev.js.map +1 -0
  16. package/dist/src/graphql/auth/resolvers.d.ts +17 -0
  17. package/dist/src/graphql/auth/resolvers.d.ts.map +1 -1
  18. package/dist/src/graphql/auth/resolvers.js +54 -0
  19. package/dist/src/graphql/auth/resolvers.js.map +1 -1
  20. package/dist/src/graphql/auth/schema.graphql +27 -5
  21. package/dist/src/graphql/auth/subgraph.d.ts +25 -0
  22. package/dist/src/graphql/auth/subgraph.d.ts.map +1 -1
  23. package/dist/src/graphql/auth/subgraph.js +46 -2
  24. package/dist/src/graphql/auth/subgraph.js.map +1 -1
  25. package/dist/src/graphql/base-subgraph.d.ts +11 -4
  26. package/dist/src/graphql/base-subgraph.d.ts.map +1 -1
  27. package/dist/src/graphql/base-subgraph.js +94 -2
  28. package/dist/src/graphql/base-subgraph.js.map +1 -1
  29. package/dist/src/graphql/document-model-subgraph.d.ts +104 -45
  30. package/dist/src/graphql/document-model-subgraph.d.ts.map +1 -1
  31. package/dist/src/graphql/document-model-subgraph.js +323 -91
  32. package/dist/src/graphql/document-model-subgraph.js.map +1 -1
  33. package/dist/src/graphql/gateway/adapter-gateway-apollo.d.ts +23 -0
  34. package/dist/src/graphql/gateway/adapter-gateway-apollo.d.ts.map +1 -0
  35. package/dist/src/graphql/gateway/adapter-gateway-apollo.js +156 -0
  36. package/dist/src/graphql/gateway/adapter-gateway-apollo.js.map +1 -0
  37. package/dist/src/graphql/gateway/adapter-http-express.d.ts +23 -0
  38. package/dist/src/graphql/gateway/adapter-http-express.d.ts.map +1 -0
  39. package/dist/src/graphql/gateway/adapter-http-express.js +155 -0
  40. package/dist/src/graphql/gateway/adapter-http-express.js.map +1 -0
  41. package/dist/src/graphql/gateway/auth-middleware.d.ts +7 -0
  42. package/dist/src/graphql/gateway/auth-middleware.d.ts.map +1 -0
  43. package/dist/src/graphql/gateway/auth-middleware.js +15 -0
  44. package/dist/src/graphql/gateway/auth-middleware.js.map +1 -0
  45. package/dist/src/graphql/gateway/factory.d.ts +11 -0
  46. package/dist/src/graphql/gateway/factory.d.ts.map +1 -0
  47. package/dist/src/graphql/gateway/factory.js +15 -0
  48. package/dist/src/graphql/gateway/factory.js.map +1 -0
  49. package/dist/src/graphql/gateway/types.d.ts +84 -0
  50. package/dist/src/graphql/gateway/types.d.ts.map +1 -0
  51. package/dist/src/{sync → graphql/gateway}/types.js.map +1 -1
  52. package/dist/src/graphql/graphql-manager.d.ts +31 -12
  53. package/dist/src/graphql/graphql-manager.d.ts.map +1 -1
  54. package/dist/src/graphql/graphql-manager.js +284 -228
  55. package/dist/src/graphql/graphql-manager.js.map +1 -1
  56. package/dist/src/graphql/index.d.ts +5 -1
  57. package/dist/src/graphql/index.d.ts.map +1 -1
  58. package/dist/src/graphql/index.js +5 -1
  59. package/dist/src/graphql/index.js.map +1 -1
  60. package/dist/src/graphql/packages/index.d.ts +2 -0
  61. package/dist/src/graphql/packages/index.d.ts.map +1 -0
  62. package/dist/src/graphql/packages/index.js +2 -0
  63. package/dist/src/graphql/packages/index.js.map +1 -0
  64. package/dist/src/graphql/packages/resolvers.d.ts +31 -0
  65. package/dist/src/graphql/packages/resolvers.d.ts.map +1 -0
  66. package/dist/src/graphql/packages/resolvers.js +37 -0
  67. package/dist/src/graphql/packages/resolvers.js.map +1 -0
  68. package/dist/src/graphql/packages/schema.graphql +50 -0
  69. package/dist/src/graphql/packages/subgraph.d.ts +55 -0
  70. package/dist/src/graphql/packages/subgraph.d.ts.map +1 -0
  71. package/dist/src/graphql/packages/subgraph.js +73 -0
  72. package/dist/src/graphql/packages/subgraph.js.map +1 -0
  73. package/dist/src/graphql/playground.d.ts.map +1 -1
  74. package/dist/src/graphql/playground.js +19 -12
  75. package/dist/src/graphql/playground.js.map +1 -1
  76. package/dist/src/graphql/reactor/adapters.d.ts +10 -2
  77. package/dist/src/graphql/reactor/adapters.d.ts.map +1 -1
  78. package/dist/src/graphql/reactor/adapters.js +36 -1
  79. package/dist/src/graphql/reactor/adapters.js.map +1 -1
  80. package/dist/src/graphql/reactor/factory.d.ts +22 -1
  81. package/dist/src/graphql/reactor/factory.d.ts.map +1 -1
  82. package/dist/src/graphql/reactor/factory.js +1 -1
  83. package/dist/src/graphql/reactor/factory.js.map +1 -1
  84. package/dist/src/graphql/reactor/gen/graphql.d.ts +355 -76
  85. package/dist/src/graphql/reactor/gen/graphql.d.ts.map +1 -1
  86. package/dist/src/graphql/reactor/gen/graphql.js +245 -10
  87. package/dist/src/graphql/reactor/gen/graphql.js.map +1 -1
  88. package/dist/src/graphql/reactor/index.d.ts +1 -1
  89. package/dist/src/graphql/reactor/index.d.ts.map +1 -1
  90. package/dist/src/graphql/reactor/index.js +1 -1
  91. package/dist/src/graphql/reactor/index.js.map +1 -1
  92. package/dist/src/graphql/reactor/operations.graphql +191 -1
  93. package/dist/src/graphql/reactor/requester.with-zod.d.ts.map +1 -1
  94. package/dist/src/graphql/reactor/requester.with-zod.js +114 -38
  95. package/dist/src/graphql/reactor/requester.with-zod.js.map +1 -1
  96. package/dist/src/graphql/reactor/resolvers.d.ts +90 -26
  97. package/dist/src/graphql/reactor/resolvers.d.ts.map +1 -1
  98. package/dist/src/graphql/reactor/resolvers.js +275 -77
  99. package/dist/src/graphql/reactor/resolvers.js.map +1 -1
  100. package/dist/src/graphql/reactor/schema.graphql +76 -30
  101. package/dist/src/graphql/reactor/subgraph.d.ts +2 -31
  102. package/dist/src/graphql/reactor/subgraph.d.ts.map +1 -1
  103. package/dist/src/graphql/reactor/subgraph.js +133 -210
  104. package/dist/src/graphql/reactor/subgraph.js.map +1 -1
  105. package/dist/src/graphql/reactor/validation.d.ts +266 -20
  106. package/dist/src/graphql/reactor/validation.d.ts.map +1 -1
  107. package/dist/src/graphql/reactor/validation.js +98 -4
  108. package/dist/src/graphql/reactor/validation.js.map +1 -1
  109. package/dist/src/graphql/sse.d.ts +42 -0
  110. package/dist/src/graphql/sse.d.ts.map +1 -0
  111. package/dist/src/graphql/sse.js +33 -0
  112. package/dist/src/graphql/sse.js.map +1 -0
  113. package/dist/src/graphql/system/index.d.ts +0 -1
  114. package/dist/src/graphql/system/index.d.ts.map +1 -1
  115. package/dist/src/graphql/system/index.js +0 -1
  116. package/dist/src/graphql/system/index.js.map +1 -1
  117. package/dist/src/graphql/types.d.ts +7 -8
  118. package/dist/src/graphql/types.d.ts.map +1 -1
  119. package/dist/src/graphql/utils.d.ts +3 -20
  120. package/dist/src/graphql/utils.d.ts.map +1 -1
  121. package/dist/src/graphql/utils.js +7 -35
  122. package/dist/src/graphql/utils.js.map +1 -1
  123. package/dist/src/migrations/002_add_document_protection.d.ts +4 -0
  124. package/dist/src/migrations/002_add_document_protection.d.ts.map +1 -0
  125. package/dist/src/migrations/002_add_document_protection.js +18 -0
  126. package/dist/src/migrations/002_add_document_protection.js.map +1 -0
  127. package/dist/src/migrations/index.d.ts.map +1 -1
  128. package/dist/src/migrations/index.js +2 -0
  129. package/dist/src/migrations/index.js.map +1 -1
  130. package/dist/src/packages/http-loader.d.ts +68 -0
  131. package/dist/src/packages/http-loader.d.ts.map +1 -0
  132. package/dist/src/packages/http-loader.js +176 -0
  133. package/dist/src/packages/http-loader.js.map +1 -0
  134. package/dist/src/packages/https-hooks.d.mts +37 -0
  135. package/dist/src/packages/https-hooks.d.mts.map +1 -0
  136. package/dist/src/packages/https-hooks.mjs +88 -0
  137. package/dist/src/packages/https-hooks.mjs.map +1 -0
  138. package/dist/src/packages/import-loader.d.ts +3 -4
  139. package/dist/src/packages/import-loader.d.ts.map +1 -1
  140. package/dist/src/packages/import-loader.js +6 -12
  141. package/dist/src/packages/import-loader.js.map +1 -1
  142. package/dist/src/packages/package-manager.d.ts +3 -4
  143. package/dist/src/packages/package-manager.d.ts.map +1 -1
  144. package/dist/src/packages/package-manager.js +2 -2
  145. package/dist/src/packages/package-manager.js.map +1 -1
  146. package/dist/src/packages/types.d.ts +9 -6
  147. package/dist/src/packages/types.d.ts.map +1 -1
  148. package/dist/src/packages/util.d.ts +4 -4
  149. package/dist/src/packages/util.d.ts.map +1 -1
  150. package/dist/src/packages/util.js +2 -2
  151. package/dist/src/packages/util.js.map +1 -1
  152. package/dist/src/packages/vite-loader.d.ts +8 -7
  153. package/dist/src/packages/vite-loader.d.ts.map +1 -1
  154. package/dist/src/packages/vite-loader.js +20 -8
  155. package/dist/src/packages/vite-loader.js.map +1 -1
  156. package/dist/src/server.d.ts +15 -28
  157. package/dist/src/server.d.ts.map +1 -1
  158. package/dist/src/server.js +137 -167
  159. package/dist/src/server.js.map +1 -1
  160. package/dist/src/services/auth.service.d.ts +11 -15
  161. package/dist/src/services/auth.service.d.ts.map +1 -1
  162. package/dist/src/services/auth.service.js +61 -40
  163. package/dist/src/services/auth.service.js.map +1 -1
  164. package/dist/src/services/authorization.service.d.ts +70 -0
  165. package/dist/src/services/authorization.service.d.ts.map +1 -0
  166. package/dist/src/services/authorization.service.js +155 -0
  167. package/dist/src/services/authorization.service.js.map +1 -0
  168. package/dist/src/services/document-permission.service.d.ts +47 -7
  169. package/dist/src/services/document-permission.service.d.ts.map +1 -1
  170. package/dist/src/services/document-permission.service.js +162 -7
  171. package/dist/src/services/document-permission.service.js.map +1 -1
  172. package/dist/src/services/package-management.service.d.ts +32 -0
  173. package/dist/src/services/package-management.service.d.ts.map +1 -0
  174. package/dist/src/services/package-management.service.js +95 -0
  175. package/dist/src/services/package-management.service.js.map +1 -0
  176. package/dist/src/services/package-storage.d.ts +23 -0
  177. package/dist/src/services/package-storage.d.ts.map +1 -0
  178. package/dist/src/services/package-storage.js +19 -0
  179. package/dist/src/services/package-storage.js.map +1 -0
  180. package/dist/src/tracing.d.ts.map +1 -1
  181. package/dist/src/tracing.js +19 -1
  182. package/dist/src/tracing.js.map +1 -1
  183. package/dist/src/types.d.ts +14 -6
  184. package/dist/src/types.d.ts.map +1 -1
  185. package/dist/src/utils/create-schema.d.ts +31 -6
  186. package/dist/src/utils/create-schema.d.ts.map +1 -1
  187. package/dist/src/utils/create-schema.js +451 -43
  188. package/dist/src/utils/create-schema.js.map +1 -1
  189. package/dist/src/utils/db.d.ts +8 -0
  190. package/dist/src/utils/db.d.ts.map +1 -1
  191. package/dist/src/utils/db.js.map +1 -1
  192. package/dist/src/utils/drive-url.d.ts +2 -0
  193. package/dist/src/utils/drive-url.d.ts.map +1 -0
  194. package/dist/src/utils/drive-url.js +3 -0
  195. package/dist/src/utils/drive-url.js.map +1 -0
  196. package/dist/src/utils/index.d.ts +1 -0
  197. package/dist/src/utils/index.d.ts.map +1 -1
  198. package/dist/src/utils/index.js +1 -0
  199. package/dist/src/utils/index.js.map +1 -1
  200. package/dist/test/auth.service.test.d.ts +10 -0
  201. package/dist/test/auth.service.test.d.ts.map +1 -0
  202. package/dist/test/auth.service.test.js +141 -0
  203. package/dist/test/auth.service.test.js.map +1 -0
  204. package/dist/test/authorization.service.test.d.ts +2 -0
  205. package/dist/test/authorization.service.test.d.ts.map +1 -0
  206. package/dist/test/authorization.service.test.js +252 -0
  207. package/dist/test/authorization.service.test.js.map +1 -0
  208. package/dist/test/connect-switchboard-reshuffle-convergence.test.d.ts +2 -0
  209. package/dist/test/connect-switchboard-reshuffle-convergence.test.d.ts.map +1 -0
  210. package/dist/test/connect-switchboard-reshuffle-convergence.test.js +204 -0
  211. package/dist/test/connect-switchboard-reshuffle-convergence.test.js.map +1 -0
  212. package/dist/test/connect-switchboard-sync.test.d.ts +2 -0
  213. package/dist/test/connect-switchboard-sync.test.d.ts.map +1 -0
  214. package/dist/test/connect-switchboard-sync.test.js +582 -0
  215. package/dist/test/connect-switchboard-sync.test.js.map +1 -0
  216. package/dist/test/document-drive-subgraph.test.d.ts +2 -0
  217. package/dist/test/document-drive-subgraph.test.d.ts.map +1 -0
  218. package/dist/test/document-drive-subgraph.test.js +244 -0
  219. package/dist/test/document-drive-subgraph.test.js.map +1 -0
  220. package/dist/test/document-model-subgraph-permissions.test.d.ts +2 -0
  221. package/dist/test/document-model-subgraph-permissions.test.d.ts.map +1 -0
  222. package/dist/test/document-model-subgraph-permissions.test.js +587 -0
  223. package/dist/test/document-model-subgraph-permissions.test.js.map +1 -0
  224. package/dist/test/drive-info-endpoint.test.d.ts +2 -0
  225. package/dist/test/drive-info-endpoint.test.d.ts.map +1 -0
  226. package/dist/test/drive-info-endpoint.test.js +123 -0
  227. package/dist/test/drive-info-endpoint.test.js.map +1 -0
  228. package/dist/test/fault-injection-sync.test.d.ts +2 -0
  229. package/dist/test/fault-injection-sync.test.d.ts.map +1 -0
  230. package/dist/test/fault-injection-sync.test.js +197 -0
  231. package/dist/test/fault-injection-sync.test.js.map +1 -0
  232. package/dist/test/gateway/adapter-gateway-apollo.test.d.ts +2 -0
  233. package/dist/test/gateway/adapter-gateway-apollo.test.d.ts.map +1 -0
  234. package/dist/test/gateway/adapter-gateway-apollo.test.js +206 -0
  235. package/dist/test/gateway/adapter-gateway-apollo.test.js.map +1 -0
  236. package/dist/test/gateway/adapter-http-express.test.d.ts +2 -0
  237. package/dist/test/gateway/adapter-http-express.test.d.ts.map +1 -0
  238. package/dist/test/gateway/adapter-http-express.test.js +17 -0
  239. package/dist/test/gateway/adapter-http-express.test.js.map +1 -0
  240. package/dist/test/gateway/auth-middleware.test.d.ts +8 -0
  241. package/dist/test/gateway/auth-middleware.test.d.ts.map +1 -0
  242. package/dist/test/gateway/auth-middleware.test.js +73 -0
  243. package/dist/test/gateway/auth-middleware.test.js.map +1 -0
  244. package/dist/test/gateway/gateway-adapter-contract.d.ts +30 -0
  245. package/dist/test/gateway/gateway-adapter-contract.d.ts.map +1 -0
  246. package/dist/test/gateway/gateway-adapter-contract.js +347 -0
  247. package/dist/test/gateway/gateway-adapter-contract.js.map +1 -0
  248. package/dist/test/gateway/http-adapter-contract.d.ts +30 -0
  249. package/dist/test/gateway/http-adapter-contract.d.ts.map +1 -0
  250. package/dist/test/gateway/http-adapter-contract.js +226 -0
  251. package/dist/test/gateway/http-adapter-contract.js.map +1 -0
  252. package/dist/test/graphql-manager.test.d.ts +12 -0
  253. package/dist/test/graphql-manager.test.d.ts.map +1 -0
  254. package/dist/test/graphql-manager.test.js +488 -0
  255. package/dist/test/graphql-manager.test.js.map +1 -0
  256. package/dist/test/index.d.ts +0 -1
  257. package/dist/test/index.d.ts.map +1 -1
  258. package/dist/test/index.js +0 -1
  259. package/dist/test/index.js.map +1 -1
  260. package/dist/test/permissions-integration.test.js +6 -20
  261. package/dist/test/permissions-integration.test.js.map +1 -1
  262. package/dist/test/push-backfill.test.d.ts +2 -0
  263. package/dist/test/push-backfill.test.d.ts.map +1 -0
  264. package/dist/test/push-backfill.test.js +299 -0
  265. package/dist/test/push-backfill.test.js.map +1 -0
  266. package/dist/test/reactor-adapters.test.js +3 -2
  267. package/dist/test/reactor-adapters.test.js.map +1 -1
  268. package/dist/test/reactor-client.test.js +172 -13
  269. package/dist/test/reactor-client.test.js.map +1 -1
  270. package/dist/test/reactor-resolvers.test.js +11 -13
  271. package/dist/test/reactor-resolvers.test.js.map +1 -1
  272. package/dist/test/reactor-subgraph-permissions.test.js +7 -36
  273. package/dist/test/reactor-subgraph-permissions.test.js.map +1 -1
  274. package/dist/test/subscriptions-sse.test.d.ts +2 -0
  275. package/dist/test/subscriptions-sse.test.d.ts.map +1 -0
  276. package/dist/test/subscriptions-sse.test.js +264 -0
  277. package/dist/test/subscriptions-sse.test.js.map +1 -0
  278. package/dist/test/subscriptions.test.js +2 -0
  279. package/dist/test/subscriptions.test.js.map +1 -1
  280. package/dist/test/utils/gql-resolver-bridge.d.ts +4 -1
  281. package/dist/test/utils/gql-resolver-bridge.d.ts.map +1 -1
  282. package/dist/test/utils/gql-resolver-bridge.js +36 -7
  283. package/dist/test/utils/gql-resolver-bridge.js.map +1 -1
  284. package/dist/test/utils.d.ts +1 -5
  285. package/dist/test/utils.d.ts.map +1 -1
  286. package/dist/test/utils.js +0 -10
  287. package/dist/test/utils.js.map +1 -1
  288. package/dist/tsconfig.tsbuildinfo +1 -1
  289. package/package.json +52 -58
  290. package/dist/src/graphql/drive-subgraph.d.ts +0 -25
  291. package/dist/src/graphql/drive-subgraph.d.ts.map +0 -1
  292. package/dist/src/graphql/drive-subgraph.js +0 -487
  293. package/dist/src/graphql/drive-subgraph.js.map +0 -1
  294. package/dist/src/graphql/system/system-subgraph.d.ts +0 -49
  295. package/dist/src/graphql/system/system-subgraph.d.ts.map +0 -1
  296. package/dist/src/graphql/system/system-subgraph.js +0 -130
  297. package/dist/src/graphql/system/system-subgraph.js.map +0 -1
  298. package/dist/src/sync/types.d.ts +0 -10
  299. package/dist/src/sync/types.d.ts.map +0 -1
  300. package/dist/src/sync/utils.d.ts +0 -7
  301. package/dist/src/sync/utils.d.ts.map +0 -1
  302. package/dist/src/sync/utils.js +0 -78
  303. package/dist/src/sync/utils.js.map +0 -1
  304. package/dist/src/utils/auth.d.ts +0 -3
  305. package/dist/src/utils/auth.d.ts.map +0 -1
  306. package/dist/src/utils/auth.js +0 -19
  307. package/dist/src/utils/auth.js.map +0 -1
  308. package/dist/test/benchmarks/load.bench.d.ts +0 -2
  309. package/dist/test/benchmarks/load.bench.d.ts.map +0 -1
  310. package/dist/test/benchmarks/load.bench.js +0 -73
  311. package/dist/test/benchmarks/load.bench.js.map +0 -1
  312. package/dist/test/benchmarks/sync.bench.d.ts +0 -2
  313. package/dist/test/benchmarks/sync.bench.d.ts.map +0 -1
  314. package/dist/test/benchmarks/sync.bench.js +0 -119
  315. package/dist/test/benchmarks/sync.bench.js.map +0 -1
  316. package/dist/test/drive-handlers.d.ts +0 -4
  317. package/dist/test/drive-handlers.d.ts.map +0 -1
  318. package/dist/test/drive-handlers.js +0 -39
  319. package/dist/test/drive-handlers.js.map +0 -1
  320. package/dist/test/drive-subgraph-permissions.test.d.ts +0 -2
  321. package/dist/test/drive-subgraph-permissions.test.d.ts.map +0 -1
  322. package/dist/test/drive-subgraph-permissions.test.js +0 -195
  323. package/dist/test/drive-subgraph-permissions.test.js.map +0 -1
  324. package/dist/test/drive.test.d.ts +0 -2
  325. package/dist/test/drive.test.d.ts.map +0 -1
  326. package/dist/test/drive.test.js +0 -142
  327. package/dist/test/drive.test.js.map +0 -1
  328. package/dist/test/identity-integration.test.d.ts +0 -2
  329. package/dist/test/identity-integration.test.d.ts.map +0 -1
  330. package/dist/test/identity-integration.test.js +0 -349
  331. package/dist/test/identity-integration.test.js.map +0 -1
  332. package/dist/test/pull-responder-transmitter.test.d.ts +0 -2
  333. package/dist/test/pull-responder-transmitter.test.d.ts.map +0 -1
  334. package/dist/test/pull-responder-transmitter.test.js +0 -220
  335. package/dist/test/pull-responder-transmitter.test.js.map +0 -1
  336. package/dist/test/push-transmitter.test.d.ts +0 -2
  337. package/dist/test/push-transmitter.test.d.ts.map +0 -1
  338. package/dist/test/push-transmitter.test.js +0 -179
  339. package/dist/test/push-transmitter.test.js.map +0 -1
  340. package/dist/test/system.test.d.ts +0 -2
  341. package/dist/test/system.test.d.ts.map +0 -1
  342. package/dist/test/system.test.js +0 -211
  343. package/dist/test/system.test.js.map +0 -1
  344. package/dist/test/three-reactor-gql-sync.test.d.ts +0 -2
  345. package/dist/test/three-reactor-gql-sync.test.d.ts.map +0 -1
  346. package/dist/test/three-reactor-gql-sync.test.js +0 -368
  347. package/dist/test/three-reactor-gql-sync.test.js.map +0 -1
  348. package/dist/test/two-reactor-gql-sync.test.d.ts +0 -2
  349. package/dist/test/two-reactor-gql-sync.test.d.ts.map +0 -1
  350. package/dist/test/two-reactor-gql-sync.test.js +0 -348
  351. package/dist/test/two-reactor-gql-sync.test.js.map +0 -1
  352. /package/dist/src/{sync → graphql/gateway}/types.js +0 -0
@@ -1,33 +1,13 @@
1
- import { ApolloGateway, LocalCompose, RemoteGraphQLDataSource, } from "@apollo/gateway";
2
- import { ApolloServer } from "@apollo/server";
3
- import { ApolloServerPluginInlineTraceDisabled } from "@apollo/server/plugin/disabled";
4
- import { ApolloServerPluginDrainHttpServer } from "@apollo/server/plugin/drainHttpServer";
5
- import { ApolloServerPluginLandingPageLocalDefault } from "@apollo/server/plugin/landingPage/default";
6
- import { expressMiddleware } from "@as-integrations/express4";
7
- import bodyParser from "body-parser";
8
- import cors from "cors";
9
- import { childLogger, debounce } from "document-drive";
10
- import { Router } from "express";
11
1
  import path from "node:path";
12
- import { setTimeout } from "node:timers/promises";
2
+ import { match } from "path-to-regexp";
3
+ import { debounce } from "../packages/util.js";
13
4
  import { AuthService } from "../services/auth.service.js";
14
- import { buildSubgraphSchemaModule, createSchema, } from "../utils/create-schema.js";
15
- import { DocumentModelSubgraphLegacy } from "./document-model-subgraph.js";
16
- import { DriveSubgraph } from "./drive-subgraph.js";
5
+ import { getAuthContext, } from "./gateway/auth-middleware.js";
6
+ import { buildSubgraphSchemaModule, createMergedSchema, createSchema, } from "../utils/create-schema.js";
7
+ import { DocumentModelSubgraph } from "./document-model-subgraph.js";
8
+ import { createGraphQLSSEHandler } from "./sse.js";
17
9
  import { useServer } from "./websocket.js";
18
- class AuthenticatedDataSource extends RemoteGraphQLDataSource {
19
- willSendRequest(options) {
20
- const { authorization } = options.context.headers;
21
- // console.log("context", options.context.headers.authorization);
22
- if (authorization && options?.request.http) {
23
- options.request.http.headers.set("authorization", authorization);
24
- }
25
- }
26
- }
27
- const DOCUMENT_MODELS_TO_EXCLUDE = [
28
- "powerhouse/document-model",
29
- "powerhouse/document-drive",
30
- ];
10
+ const DOCUMENT_MODELS_TO_EXCLUDE = [];
31
11
  /**
32
12
  * Check if a document model has any operations with valid schemas.
33
13
  * Document models without valid operation schemas cannot generate valid subgraph schemas.
@@ -36,126 +16,153 @@ function hasOperationSchemas(documentModel) {
36
16
  const specification = documentModel.documentModel.global.specifications.at(-1);
37
17
  if (!specification)
38
18
  return false;
39
- // Check if any operation has a schema with actual GraphQL type definitions
40
19
  const hasValidSchema = (schema) => schema && /\b(input|type|enum|union|interface)\s+\w+/.test(schema);
41
20
  return specification.modules.some((module) => module.operations.some((op) => hasValidSchema(op.schema)));
42
21
  }
22
+ /**
23
+ * Filter document models to keep only the latest version of each unique document model.
24
+ */
25
+ function filterLatestDocumentModelVersions(documentModels) {
26
+ const latestByName = new Map();
27
+ for (const documentModel of documentModels) {
28
+ const name = documentModel.documentModel.global.name;
29
+ const existing = latestByName.get(name);
30
+ if (!existing) {
31
+ latestByName.set(name, documentModel);
32
+ continue;
33
+ }
34
+ const currentVersion = documentModel.documentModel.global.specifications.at(-1)?.version ?? 0;
35
+ const existingVersion = existing.documentModel.global.specifications.at(-1)?.version ?? 0;
36
+ if (currentVersion > existingVersion) {
37
+ latestByName.set(name, documentModel);
38
+ }
39
+ }
40
+ return Array.from(latestByName.values());
41
+ }
43
42
  const DefaultFeatureFlags = {
44
43
  enableDocumentModelSubgraphs: true,
45
44
  };
46
45
  export class GraphQLManager {
47
46
  path;
48
- app;
49
47
  httpServer;
50
48
  wsServer;
51
- reactor;
52
49
  reactorClient;
53
50
  relationalDb;
54
51
  analyticsStore;
55
52
  syncManager;
53
+ logger;
54
+ httpAdapter;
55
+ gatewayAdapter;
56
56
  authConfig;
57
57
  documentPermissionService;
58
58
  featureFlags;
59
+ port;
60
+ authorizationService;
59
61
  initialized = false;
60
- coreRouter = Router();
61
62
  coreSubgraphsMap = new Map();
62
- reactorRouter = Router();
63
63
  contextFields = {};
64
64
  subgraphs = new Map();
65
65
  authService = null;
66
- logger = childLogger(["reactor-api", "graphql-manager"]);
67
- apolloLogger = childLogger([
68
- "reactor-api",
69
- "graphql-manager",
70
- "apollo",
71
- ]);
72
- constructor(path, app, httpServer, wsServer, reactor, reactorClient, relationalDb, analyticsStore, syncManager, authConfig, documentPermissionService, featureFlags = DefaultFeatureFlags) {
66
+ subgraphWsDisposers = new Map();
67
+ #authMiddleware;
68
+ /** Cached document models for schema generation - updated on init and regenerate */
69
+ cachedDocumentModels = [];
70
+ subgraphHandlerCache = new Map();
71
+ constructor(path, httpServer, wsServer, reactorClient, relationalDb, analyticsStore, syncManager, logger, httpAdapter, gatewayAdapter, authConfig, documentPermissionService, featureFlags = DefaultFeatureFlags, port = 4001, authorizationService) {
73
72
  this.path = path;
74
- this.app = app;
75
73
  this.httpServer = httpServer;
76
74
  this.wsServer = wsServer;
77
- this.reactor = reactor;
78
75
  this.reactorClient = reactorClient;
79
76
  this.relationalDb = relationalDb;
80
77
  this.analyticsStore = analyticsStore;
81
78
  this.syncManager = syncManager;
79
+ this.logger = logger;
80
+ this.httpAdapter = httpAdapter;
81
+ this.gatewayAdapter = gatewayAdapter;
82
82
  this.authConfig = authConfig;
83
83
  this.documentPermissionService = documentPermissionService;
84
84
  this.featureFlags = featureFlags;
85
+ this.port = port;
86
+ this.authorizationService = authorizationService;
85
87
  if (this.authConfig) {
86
88
  this.authService = new AuthService(this.authConfig);
87
- this.setAdditionalContextFields(this.authService.getAdditionalContextFields());
88
89
  }
89
90
  }
90
- async init(coreSubgraphs) {
91
+ async init(coreSubgraphs, authMiddleware) {
92
+ this.#authMiddleware = authMiddleware;
91
93
  this.logger.debug(`Initializing Subgraph Manager...`);
92
94
  // check if Document Drive model is available
93
- const models = this.reactor.getDocumentModelModules();
95
+ const modulesResult = await this.reactorClient.getDocumentModelModules();
96
+ const models = modulesResult.results;
97
+ // Cache models for schema generation
98
+ this.cachedDocumentModels = models;
94
99
  const driveModel = models.find((it) => it.documentModel.global.name === "DocumentDrive");
95
100
  if (!driveModel) {
96
101
  throw new Error("DocumentDrive model required");
97
102
  }
98
- this.coreRouter.use(cors());
99
- this.coreRouter.use(bodyParser.json({ limit: "50mb" }));
100
- this.coreRouter.use(bodyParser.urlencoded({ extended: true, limit: "50mb" }));
101
- this.app.use("/", (req, res, next) => {
102
- this.setAdditionalContextFields({
103
- user: req.user,
104
- isAdmin: (address) => !req.auth_enabled
105
- ? true
106
- : (req.admins
107
- ?.map((a) => a.toLowerCase())
108
- .includes(address.toLowerCase() ?? "") ?? false),
109
- isUser: (address) => !req.auth_enabled
110
- ? true
111
- : (req.users
112
- ?.map((a) => a.toLowerCase())
113
- .includes(address.toLowerCase() ?? "") ?? false),
114
- isGuest: (address) => !req.auth_enabled
115
- ? true
116
- : (req.guests
117
- ?.map((a) => a.toLowerCase())
118
- .includes(address.toLowerCase() ?? "") ?? false),
119
- });
120
- this.coreRouter(req, res, next);
121
- });
122
- this.app.use("/", (req, res, next) => {
123
- this.setAdditionalContextFields({
124
- user: req.user,
125
- isAdmin: (address) => !req.auth_enabled
126
- ? true
127
- : (req.admins
128
- ?.map((a) => a.toLowerCase())
129
- .includes(address.toLowerCase() ?? "") ?? false),
130
- isUser: (address) => !req.auth_enabled
131
- ? true
132
- : (req.users
133
- ?.map((a) => a.toLowerCase())
134
- .includes(address.toLowerCase() ?? "") ?? false),
135
- isGuest: (address) => !req.auth_enabled
136
- ? true
137
- : (req.guests
138
- ?.map((a) => a.toLowerCase())
139
- .includes(address.toLowerCase() ?? "") ?? false),
140
- });
141
- this.reactorRouter(req, res, next);
103
+ await this.gatewayAdapter.start(this.httpServer);
104
+ this.httpAdapter.setupMiddleware({ bodyLimit: "50mb" });
105
+ // Register REST endpoint for drive info as a framework-agnostic FetchHandler.
106
+ const driveRoutePath = path.join(this.path, "d/:drive");
107
+ const driveMatcher = match(driveRoutePath);
108
+ this.httpAdapter.mount(driveRoutePath, async (request) => {
109
+ const url = new URL(request.url);
110
+ const matched = driveMatcher(url.pathname);
111
+ const driveIdOrSlug = matched ? matched.params.drive : undefined;
112
+ if (!driveIdOrSlug) {
113
+ return Response.json({ error: "Drive ID or slug is required" }, { status: 400 });
114
+ }
115
+ try {
116
+ const driveDoc = await this.reactorClient.get(driveIdOrSlug);
117
+ const forwardedProto = request.headers.get("x-forwarded-proto");
118
+ const protocol = (forwardedProto ?? url.protocol.replace(":", "")) + ":";
119
+ const host = request.headers.get("host") ?? "";
120
+ const basePath = this.path === "/" ? "" : this.path;
121
+ const graphqlEndpoint = `${protocol}//${host}${basePath}/graphql/r`;
122
+ return Response.json({
123
+ id: driveDoc.header.id,
124
+ slug: driveDoc.header.slug,
125
+ meta: driveDoc.header.meta,
126
+ name: driveDoc.state.global.name,
127
+ icon: driveDoc.state.global.icon ?? undefined,
128
+ ...(graphqlEndpoint && { graphqlEndpoint }),
129
+ });
130
+ }
131
+ catch (error) {
132
+ this.logger.debug(`Drive not found: ${driveIdOrSlug}`, error);
133
+ return Response.json({ error: "Drive not found" }, { status: 404 });
134
+ }
142
135
  });
136
+ this.logger.info(`Registered REST endpoint: GET ${driveRoutePath}`);
143
137
  await this.#setupCoreSubgraphs("graphql", coreSubgraphs);
144
138
  if (this.featureFlags.enableDocumentModelSubgraphs) {
145
- await this.#setupDocumentModelSubgraphs("graphql", this.reactor.getDocumentModelModules());
139
+ await this.#setupDocumentModelSubgraphs("graphql", models);
146
140
  }
147
- this.reactor.on("documentModelModules", (documentModels) => {
148
- if (this.featureFlags.enableDocumentModelSubgraphs) {
149
- this.#setupDocumentModelSubgraphs("graphql", documentModels)
150
- .then(() => this.updateRouter())
151
- .catch((error) => this.logger.error(error));
152
- }
153
- else {
154
- this.updateRouter().catch((error) => this.logger.error(error));
155
- }
156
- });
141
+ await this.#createSupergraphGateway();
157
142
  return this.updateRouter();
158
143
  }
144
+ /**
145
+ * Regenerate document model subgraphs when models are dynamically loaded.
146
+ * Fetches current modules from reactor client (source of truth).
147
+ */
148
+ async regenerateDocumentModelSubgraphs() {
149
+ if (!this.featureFlags.enableDocumentModelSubgraphs) {
150
+ return;
151
+ }
152
+ try {
153
+ const modulesResult = await this.reactorClient.getDocumentModelModules();
154
+ const models = modulesResult.results;
155
+ // Update cached models for schema generation
156
+ this.cachedDocumentModels = models;
157
+ await this.#setupDocumentModelSubgraphs("graphql", models);
158
+ await this.updateRouter();
159
+ this.logger.info("Regenerated document model subgraphs with @count models", models.length);
160
+ }
161
+ catch (error) {
162
+ this.logger.error("Failed to regenerate document model subgraphs", error);
163
+ throw error;
164
+ }
165
+ }
159
166
  async #setupCoreSubgraphs(supergraph, coreSubgraphs) {
160
167
  for (const subgraph of coreSubgraphs) {
161
168
  try {
@@ -165,87 +172,100 @@ export class GraphQLManager {
165
172
  this.logger.error(`Failed to setup core subgraph ${subgraph.name}`, error);
166
173
  }
167
174
  }
168
- // special case for drive
169
- await this.registerSubgraph(DriveSubgraph, undefined, true);
170
- return this.#setupSubgraphs(this.coreSubgraphsMap, this.coreRouter);
175
+ return this.#setupSubgraphs(this.coreSubgraphsMap);
171
176
  }
172
177
  async #setupDocumentModelSubgraphs(supergraph, documentModels) {
173
- for (const documentModel of documentModels) {
178
+ const latestDocumentModels = filterLatestDocumentModelVersions(documentModels);
179
+ for (const documentModel of latestDocumentModels) {
174
180
  if (DOCUMENT_MODELS_TO_EXCLUDE.includes(documentModel.documentModel.global.id)) {
175
- continue; // Skip the legacy document model
181
+ continue;
176
182
  }
177
183
  if (!hasOperationSchemas(documentModel)) {
178
- continue; // Skip document models without operation schemas
184
+ continue;
179
185
  }
180
186
  try {
181
- const subgraphInstance = new DocumentModelSubgraphLegacy(documentModel, {
187
+ const subgraphInstance = new DocumentModelSubgraph(documentModel, {
182
188
  relationalDb: this.relationalDb,
183
189
  analyticsStore: this.analyticsStore,
184
- reactor: this.reactor,
185
190
  reactorClient: this.reactorClient,
186
191
  graphqlManager: this,
187
192
  syncManager: this.syncManager,
188
193
  path: this.path,
189
194
  documentPermissionService: this.documentPermissionService,
195
+ authorizationService: this.authorizationService,
190
196
  });
191
197
  await this.#addSubgraphInstance(subgraphInstance, supergraph, false);
192
198
  }
193
199
  catch (error) {
194
200
  this.logger.error(`Failed to setup document model subgraph for ${documentModel.documentModel.global.id}`, error instanceof Error ? error.message : error);
195
- this.logger.debug(error);
201
+ this.logger.debug("@error", error);
196
202
  }
197
203
  }
198
- // special case for drive
199
- await this.registerSubgraph(DriveSubgraph, undefined, true);
200
- return this.#setupSubgraphs(this.coreSubgraphsMap, this.coreRouter);
204
+ // Document model subgraph instances are added to this.subgraphs above.
205
+ // Their handlers are wired in _updateRouter() #setupSubgraphs(this.subgraphs),
206
+ // which is called at the end of init() via updateRouter(). We intentionally do
207
+ // NOT call #setupSubgraphs(this.coreSubgraphsMap) here - doing so would
208
+ // create duplicate Apollo servers for the same core-subgraph schemas, which
209
+ // in the new IGatewayAdapter architecture hangs #waitForServer and blocks init().
201
210
  }
202
211
  async #addSubgraphInstance(subgraphInstance, supergraph = "", core = false) {
203
- await subgraphInstance.onSetup?.();
204
212
  const subgraphsMap = core ? this.coreSubgraphsMap : this.subgraphs;
205
213
  const subgraphs = subgraphsMap.get(supergraph) ?? [];
206
214
  const existingSubgraph = subgraphs.find((it) => it.name === subgraphInstance.name);
215
+ if (existingSubgraph) {
216
+ this.logger.debug(`Skipping duplicate subgraph: ${subgraphInstance.name}`);
217
+ return existingSubgraph;
218
+ }
219
+ await subgraphInstance.onSetup?.();
207
220
  subgraphs.push(subgraphInstance);
208
221
  subgraphsMap.set(supergraph, subgraphs);
209
- // also add to global graphql supergraph
210
222
  if (supergraph !== "" && supergraph !== "graphql") {
211
223
  subgraphsMap.get("graphql")?.push(subgraphInstance);
212
224
  }
213
- const logMessage = `Registered ${this.path.endsWith("/") ? this.path : this.path + "/"}${supergraph ? supergraph + "/" : ""}${subgraphInstance.name} subgraph.`;
214
- if (!existingSubgraph) {
215
- this.logger.info(logMessage);
216
- }
217
- else {
218
- this.logger.debug(logMessage);
219
- }
225
+ this.logger.info(`Registered ${this.path.endsWith("/") ? this.path : this.path + "/"}${supergraph ? supergraph + "/" : ""}${subgraphInstance.name} subgraph.`);
220
226
  return subgraphInstance;
221
227
  }
228
+ /**
229
+ * Register a pre-constructed subgraph instance.
230
+ * Use this when you need to pass custom dependencies to a subgraph.
231
+ */
232
+ async registerSubgraphInstance(subgraphInstance, supergraph = "", core = false) {
233
+ return this.#addSubgraphInstance(subgraphInstance, supergraph, core);
234
+ }
235
+ /**
236
+ * Get the base path used for subgraph registration.
237
+ */
238
+ getBasePath() {
239
+ return this.path;
240
+ }
222
241
  async registerSubgraph(subgraph, supergraph = "", core = false) {
223
242
  const subgraphInstance = new subgraph({
224
243
  relationalDb: this.relationalDb,
225
244
  analyticsStore: this.analyticsStore,
226
- reactor: this.reactor,
227
245
  reactorClient: this.reactorClient,
228
246
  graphqlManager: this,
229
247
  syncManager: this.syncManager,
230
248
  path: this.path,
231
249
  documentPermissionService: this.documentPermissionService,
250
+ authorizationService: this.authorizationService,
232
251
  });
233
252
  return this.#addSubgraphInstance(subgraphInstance, supergraph, core);
234
253
  }
235
254
  updateRouter = debounce(this._updateRouter.bind(this), 1000);
236
255
  async _updateRouter() {
237
256
  this.logger.debug("Updating router");
238
- const newRouter = Router();
239
- newRouter.use(cors());
240
- newRouter.use(bodyParser.json());
241
- // @todo:
242
- // if auth enabled, subgraphs are only available to guests, users and admins
243
- // if auth enabled, set req user to the graphql context
244
- // if auth disabled, subgraphs are available to all
245
- await this.#setupSubgraphs(this.subgraphs, newRouter);
246
- this.reactorRouter = newRouter;
247
- await this.#createApolloGateway();
248
- return;
257
+ await this.#setupSubgraphs(this.subgraphs);
258
+ try {
259
+ await this.gatewayAdapter.updateSupergraph();
260
+ this.logger.debug("Updated Apollo Gateway supergraph");
261
+ }
262
+ catch (error) {
263
+ this.logger.error("Failed to update Apollo Gateway supergraph", error);
264
+ }
265
+ // Refresh the supergraph-level SSE handler so it picks up
266
+ // any newly registered subscription-enabled subgraphs.
267
+ const superGraphPath = path.join(this.path, "graphql");
268
+ this.#setupSupergraphSSE(superGraphPath);
249
269
  }
250
270
  getAdditionalContextFields = () => {
251
271
  return this.contextFields;
@@ -262,7 +282,6 @@ export class GraphQLManager {
262
282
  const context = {
263
283
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
264
284
  headers: connectionParams,
265
- driveServer: this.reactor,
266
285
  db: this.relationalDb,
267
286
  ...this.getAdditionalContextFields(),
268
287
  };
@@ -271,6 +290,29 @@ export class GraphQLManager {
271
290
  }
272
291
  return context;
273
292
  }
293
+ #makeContextFactory() {
294
+ return (request) => {
295
+ const authCtx = getAuthContext(request);
296
+ const headers = {};
297
+ request.headers.forEach((v, k) => {
298
+ headers[k] = v;
299
+ });
300
+ return Promise.resolve({
301
+ headers,
302
+ db: this.relationalDb,
303
+ ...this.getAdditionalContextFields(),
304
+ user: authCtx?.user,
305
+ isAdmin: authCtx
306
+ ? (addr) => !authCtx.auth_enabled
307
+ ? true
308
+ : authCtx.admins.includes(addr.toLowerCase())
309
+ : () => true,
310
+ });
311
+ };
312
+ }
313
+ #makeWsContextFactory() {
314
+ return (connectionParams) => this.#createWebSocketContext(connectionParams);
315
+ }
274
316
  setSupergraph(supergraph, subgraphs) {
275
317
  this.subgraphs.set(supergraph, subgraphs);
276
318
  const globalSubgraphs = this.subgraphs.get("graphql");
@@ -284,6 +326,13 @@ export class GraphQLManager {
284
326
  }
285
327
  async shutdown() {
286
328
  this.logger.info("Shutting down GraphQL Manager");
329
+ // Dispose per-subgraph WebSocket handlers before closing the WS server.
330
+ for (const disposer of this.subgraphWsDisposers.values()) {
331
+ await disposer.dispose();
332
+ }
333
+ this.subgraphWsDisposers.clear();
334
+ // Stop all Apollo servers (per-subgraph + federation gateway) via the adapter.
335
+ await this.gatewayAdapter.stop();
287
336
  return new Promise((resolve) => {
288
337
  this.wsServer.close(() => {
289
338
  this.logger.info("WebSocket server closed");
@@ -291,58 +340,53 @@ export class GraphQLManager {
291
340
  });
292
341
  });
293
342
  }
294
- #createApolloServer(schema) {
295
- return new ApolloServer({
296
- schema,
297
- logger: this.apolloLogger,
298
- introspection: true,
299
- plugins: [
300
- ApolloServerPluginInlineTraceDisabled(),
301
- ApolloServerPluginLandingPageLocalDefault(),
302
- ],
303
- });
304
- }
305
- async #waitForServer(server) {
306
- try {
307
- server.assertStarted("waitForServer");
308
- return true;
309
- }
310
- catch {
311
- await setTimeout(100);
312
- return this.#waitForServer(server);
313
- }
314
- }
315
343
  #getSubgraphPath(subgraph, supergraph) {
316
344
  return path.join(subgraph.path ?? "", supergraph, subgraph.name);
317
345
  }
318
- async #setupSubgraphs(subgraphsMap, router) {
346
+ async #setupSubgraphs(subgraphsMap) {
319
347
  for (const [supergraph, subgraphs] of subgraphsMap.entries()) {
320
348
  for (const subgraph of subgraphs) {
321
349
  this.logger.debug(`Setting up subgraph ${subgraph.name}`);
350
+ const subgraphPath = this.#getSubgraphPath(subgraph, supergraph);
322
351
  try {
323
- // create subgraph schema
324
- const schema = createSchema(this.reactor, subgraph.resolvers, subgraph.typeDefs);
325
- // create and start apollo server
326
- const server = this.#createApolloServer(schema);
327
- server.startInBackgroundHandlingStartupErrorsByLoggingAndFailingAllRequests();
328
- await this.#waitForServer(server);
352
+ // Skip if handler already cached - subgraphs are deduplicated by name
353
+ // in #addSubgraphInstance, so a cached path means the schema is unchanged.
354
+ // This prevents unbounded schema/server creation across repeated
355
+ // _updateRouter() calls. The handler was already mounted on first setup,
356
+ // so no re-mount is needed.
357
+ if (this.subgraphHandlerCache.has(subgraphPath)) {
358
+ continue;
359
+ }
360
+ const schema = createSchema(this.cachedDocumentModels, subgraph.resolvers, subgraph.typeDefs);
361
+ const rawHandler = await this.gatewayAdapter.createHandler(schema, this.#makeContextFactory());
362
+ const fetchHandler = this.#authMiddleware
363
+ ? this.#authMiddleware(rawHandler)
364
+ : rawHandler;
365
+ this.subgraphHandlerCache.set(subgraphPath, fetchHandler);
366
+ this.httpAdapter.mount(subgraphPath, fetchHandler);
329
367
  if (subgraph.hasSubscriptions) {
330
- useServer({
331
- schema,
332
- context: async (ctx) => {
333
- const connectionParams = (ctx.connectionParams ??
334
- {});
335
- return this.#createWebSocketContext(connectionParams);
336
- },
337
- }, this.wsServer);
338
- this.logger.info(`WebSocket subscriptions enabled for ${subgraph.name}`);
368
+ try {
369
+ const wsDisposer = this.gatewayAdapter.attachWebSocket(this.wsServer, schema, this.#makeWsContextFactory());
370
+ this.subgraphWsDisposers.set(subgraphPath, wsDisposer);
371
+ this.logger.debug(`WebSocket subscriptions enabled for ${subgraph.name}`);
372
+ }
373
+ catch (error) {
374
+ this.logger.error("Failed to setup websocket for subgraph @name at path @path: @error", subgraph.name, subgraphPath, error);
375
+ }
376
+ // Set up SSE (Server-Sent Events) transport alongside WebSocket.
377
+ // Clients can use SSE by sending POST requests with
378
+ // Accept: text/event-stream to the /stream sub-path.
379
+ try {
380
+ this.#setupSSEHandler(schema, subgraphPath);
381
+ this.logger.debug(`SSE subscriptions enabled for ${subgraph.name}`);
382
+ }
383
+ catch (error) {
384
+ this.logger.error("Failed to setup SSE for subgraph @name at path @path: @error", subgraph.name, subgraphPath, error);
385
+ }
339
386
  }
340
- const path = this.#getSubgraphPath(subgraph, supergraph);
341
- this.#setupApolloExpressMiddleware(server, router, path);
342
387
  }
343
388
  catch (error) {
344
- this.logger.error(`Failed to setup subgraph ${subgraph.name} at path ${this.#getSubgraphPath(subgraph, supergraph)}`);
345
- this.logger.error(error);
389
+ this.logger.error("Failed to setup subgraph @name at path @path: @error", subgraph.name, subgraphPath, error);
346
390
  }
347
391
  }
348
392
  }
@@ -357,75 +401,87 @@ export class GraphQLManager {
357
401
  continue;
358
402
  }
359
403
  for (const subgraph of subgraphs) {
360
- const path = this.#getSubgraphPath(subgraph, supergraph);
361
- subgraphsMap.set(path, subgraph);
404
+ const subgraphPath = this.#getSubgraphPath(subgraph, supergraph);
405
+ subgraphsMap.set(subgraphPath, subgraph);
362
406
  }
363
407
  }
364
408
  return subgraphsMap;
365
409
  }
366
410
  #buildSubgraphSchemaModule(subgraph) {
367
- return buildSubgraphSchemaModule(this.reactor, subgraph.resolvers, subgraph.typeDefs);
411
+ return buildSubgraphSchemaModule(this.cachedDocumentModels, subgraph.resolvers, subgraph.typeDefs);
368
412
  }
369
- async #createApolloGateway() {
413
+ #getSubgraphDefinitions() {
370
414
  const subgraphs = this.#getAllSubgraphs();
415
+ const herokuOrLocal = process.env.HEROKU_APP_DEFAULT_DOMAIN_NAME
416
+ ? `https://${process.env.HEROKU_APP_DEFAULT_DOMAIN_NAME}`
417
+ : `http://localhost:${this.port}`;
418
+ return Array.from(subgraphs.entries()).map(([subgraphPath, subgraph]) => ({
419
+ name: subgraphPath.replace("/", ":"),
420
+ typeDefs: this.#buildSubgraphSchemaModule(subgraph).typeDefs,
421
+ url: `${herokuOrLocal}${subgraphPath}`,
422
+ }));
423
+ }
424
+ async #createSupergraphGateway() {
425
+ const superGraphPath = path.join(this.path, "graphql");
426
+ const rawHandler = await this.gatewayAdapter.createSupergraphHandler(() => this.#getSubgraphDefinitions(), this.httpServer, this.#makeContextFactory());
427
+ const fetchHandler = this.#authMiddleware
428
+ ? this.#authMiddleware(rawHandler)
429
+ : rawHandler;
430
+ this.httpAdapter.mount(superGraphPath, fetchHandler);
431
+ // Set up SSE subscriptions at the supergraph level (/graphql/stream).
432
+ // Build a subscription schema from all subgraphs that define subscriptions.
433
+ this.#setupSupergraphSSE(superGraphPath);
434
+ if (!this.initialized) {
435
+ this.logger.info(`Registered ${superGraphPath} supergraph `);
436
+ this.initialized = true;
437
+ }
438
+ return;
439
+ }
440
+ /**
441
+ * Set up an SSE subscription endpoint at the supergraph level.
442
+ * Merges the schemas of all subscription-enabled subgraphs so that
443
+ * clients can subscribe at /graphql/stream without knowing individual
444
+ * subgraph paths.
445
+ */
446
+ #setupSupergraphSSE(superGraphPath) {
447
+ const allSubgraphs = this.#getAllSubgraphs();
448
+ const modules = Array.from(allSubgraphs.values())
449
+ .filter((subgraph) => subgraph.hasSubscriptions)
450
+ .map((subgraph) => this.#buildSubgraphSchemaModule(subgraph));
451
+ if (modules.length === 0) {
452
+ return;
453
+ }
371
454
  try {
372
- const herokuOrLocal = process.env.HEROKU_APP_DEFAULT_DOMAIN_NAME
373
- ? `https://${process.env.HEROKU_APP_DEFAULT_DOMAIN_NAME}`
374
- : `http://localhost:${process.env.PORT ?? 4001}`;
375
- const serviceList = Array.from(subgraphs.entries()).map(([path, subgraph]) => ({
376
- name: path.replace("/", ":"),
377
- typeDefs: this.#buildSubgraphSchemaModule(subgraph).typeDefs,
378
- url: `${herokuOrLocal}${path}`,
379
- }));
380
- const gateway = new ApolloGateway({
381
- supergraphSdl: new LocalCompose({
382
- localServiceList: serviceList,
383
- }),
384
- buildService: (serviceConfig) => {
385
- return new AuthenticatedDataSource(serviceConfig);
386
- },
387
- });
388
- const server = new ApolloServer({
389
- gateway,
390
- logger: this.apolloLogger,
391
- introspection: true,
392
- plugins: [
393
- ApolloServerPluginDrainHttpServer({
394
- httpServer: this.httpServer,
395
- }),
396
- ApolloServerPluginInlineTraceDisabled(),
397
- ApolloServerPluginLandingPageLocalDefault(),
398
- ],
399
- });
400
- await server.start();
401
- await this.#waitForServer(server);
402
- const superGraphPath = path.join(this.path, "graphql");
403
- this.#setupApolloExpressMiddleware(server, this.reactorRouter, superGraphPath);
404
- if (!this.initialized) {
405
- this.logger.info(`Registered ${superGraphPath} supergraph `);
406
- this.initialized = true;
407
- }
408
- return server;
455
+ const mergedSchema = createMergedSchema(modules);
456
+ this.#setupSSEHandler(mergedSchema, superGraphPath);
457
+ this.logger.debug(`SSE subscriptions enabled at supergraph level (merged from ${modules.length} subgraph(s))`);
409
458
  }
410
- catch (e) {
411
- if (e instanceof Error) {
412
- this.logger.error(e.message);
413
- }
414
- else {
415
- this.logger.error("Could not create Apollo Gateway", e);
416
- }
459
+ catch (error) {
460
+ this.logger.error("Failed to setup supergraph SSE: @error", error);
417
461
  }
418
462
  }
419
- #setupApolloExpressMiddleware(server, router, path) {
420
- router.use(path, expressMiddleware(server, {
421
- context: ({ req }) => Promise.resolve({
463
+ /**
464
+ * Set up a GraphQL-over-SSE handler at `<basePath>/stream`.
465
+ *
466
+ * Clients subscribe by sending a POST with `Accept: text/event-stream`
467
+ * to the `/stream` sub-path. Authentication is handled by the normal
468
+ * Express middleware (Authorization header), unlike WebSocket which
469
+ * needs its own connectionParams-based auth.
470
+ */
471
+ #setupSSEHandler(schema, basePath) {
472
+ const ssePath = basePath + "/stream";
473
+ const sseHandler = createGraphQLSSEHandler({
474
+ schema,
475
+ contextFactory: (req) => ({
422
476
  headers: req.headers,
423
- driveId: req.params.drive ?? undefined,
424
- driveServer: this.reactor,
477
+ driveId: req.params?.drive ?? undefined,
425
478
  db: this.relationalDb,
426
479
  ...this.getAdditionalContextFields(),
427
480
  }),
428
- }));
481
+ });
482
+ // SSE handler is Express-specific; mount directly on the underlying app.
483
+ // TODO: replace sse.ts with a Fetch API handler so this can use httpAdapter.mount()
484
+ this.httpAdapter.handle.use(ssePath, sseHandler);
429
485
  }
430
486
  }
431
487
  //# sourceMappingURL=graphql-manager.js.map