Skip to content

Conversation

@notaphplover
Copy link
Member

@notaphplover notaphplover commented Dec 24, 2025

Added

  • Added apollo subscriptions ws package

Changed

  • Updated apolloServerPluginsServiceIdentifier to be a plugin array service identifier

Removed

  • Removed httpServerServiceIdentifier

Summary by CodeRabbit

  • New Features

    • GraphQL subscriptions over WebSocket added (new subscription package with configurable path and exported server identifier).
  • Changes

    • Plugin wiring updated to support multiple plugin providers (inputs flattened).
    • Several DI bindings switched to singleton scope.
    • Removed public export of the HTTP server identifier.
  • Documentation

    • Added README for the subscription package.
  • Tests

    • Added unit and integration tests for the subscription server module.
  • Chores

    • New package configs, ignore rules, lint/format/test setups, and version bumps.

✏️ Tip: You can customize this high-level summary in your review settings.

@notaphplover notaphplover self-assigned this Dec 24, 2025
@changeset-bot
Copy link

changeset-bot bot commented Dec 24, 2025

🦋 Changeset detected

Latest commit: 0707e31

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@inversifyjs/apollo-express Minor
@inversifyjs/apollo-subscription-ws Minor
@inversifyjs/apollo-core Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link

coderabbitai bot commented Dec 24, 2025

📝 Walkthrough

Walkthrough

Refactors plugin DI from optional single to multi-value bindings with singleton scoping across apollo-core and apollo-express, removes the exported httpServerServiceIdentifier from apollo-express, and adds a new apollo-subscription-ws package that provides WebSocket-based GraphQL subscription wiring and tests.

Changes

Cohort / File(s) Summary
Changesets
.changeset/fair-vans-strive.md, .changeset/perky-eggs-serve.md, .changeset/three-shrimps-make.md
Adds changesets for minor bumps: apollo-express (removes httpServerServiceIdentifier), apollo-subscription-ws (adds ApolloSubscriptionServerContainerModule, wsServerServiceIdentifier), and apollo-core (plugin DI type change).
Apollo Core — Plugin type & DI
packages/apollo-core/src/apollo/models/apolloServerPluginsServiceIdentifier.ts, packages/apollo-core/src/apollo/modules/ApolloServerContainerModule.ts
Changes plugin service identifier type to ApolloServerPlugin<any>[], marks plugin provider isMultiple: true, flattens plugin arrays with .flat(), and adds .inSingletonScope() to server bindings.
Apollo Core — Tests
packages/apollo-core/src/apollo/modules/ApolloServerContainerModule.spec.ts
Updates mocks to support chained fluent API (inSingletonScope, toResolvedValue), adds test asserting .toResolvedValue().inSingletonScope() and changes expected binding options from optional: true to isMultiple: true.
Apollo Express — Removed export & API
packages/apollo-express/src/apollo/models/httpServerServiceIdentifier.ts, packages/apollo-express/src/index.ts
Removes the httpServerServiceIdentifier module and its export from the apollo-express public index.
Apollo Express — DI scoping & tests
packages/apollo-express/src/apollo/modules/ApolloExpressServerContainerModule.ts, packages/apollo-express/src/apollo/modules/ApolloExpressServerContainerModule.spec.ts
Adds .inSingletonScope() to several DI bindings and updates tests/mocks to expect chained fluent calls.
Apollo Express — Type-only import adjustments
packages/apollo-express/src/apollo/controllers/buildApolloServerExpressController.int.spec.ts
Converts several value imports to type-only imports (Apollo types, Express, Inversify types) in integration spec.
apollo-subscription-ws — Package scaffolding
packages/apollo-subscription-ws/package.json, README.md, .gitignore, .npmignore, .lintstagedrc.json, eslint.config.mjs, prettier.config.mjs, vitest.config.mjs, tsconfig.json, tsconfig.esm.json
New package with tooling/config (ESLint, Prettier, Vitest, tsconfigs), publish metadata, dependencies (graphql-ws, peer deps), and CI/dev scripts.
apollo-subscription-ws — Models & API
packages/apollo-subscription-ws/src/apollo/models/ApolloSubscriptionServerContainerModuleOptions.ts, packages/apollo-subscription-ws/src/apollo/models/wsServerServiceIdentifier.ts, packages/apollo-subscription-ws/src/index.ts
Adds ApolloSubscriptionServerContainerModuleOptions interface, wsServerServiceIdentifier symbol, and re-exports module/options/identifier from package index.
apollo-subscription-ws — Module implementation
packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.ts
New Inversify ContainerModule that binds a WebSocketServer factory (using HTTP server and path) and registers an Apollo plugin that manages graphql-ws lifecycle (useServer, drainServer → dispose).
apollo-subscription-ws — Tests
packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.spec.ts, .../ApolloSubscriptionServerContainerModule.int.spec.ts
Adds unit tests verifying DI bindings, plugin lifecycle (serverWillStart/drainServer/dispose), and an integration test that starts HTTP + WS servers and validates HTTP query and WebSocket subscription flow.
Misc — .gitignore adjustments
packages/apollo-core/.gitignore, packages/apollo-express/.gitignore, packages/codegen/.gitignore
Anchor Turborepo ignore pattern changed from .turbo/ to /.turbo/ in several package .gitignore files.

Sequence Diagram(s)

sequenceDiagram
    participant Container as Inversify Container
    participant ApolloCore as Apollo Core Module
    participant Plugins as Multiple Plugin Providers
    participant ApolloServer as Apollo Server

    Container->>ApolloCore: load ApolloServerContainerModule
    ApolloCore->>Plugins: bind apolloServerPluginsServiceIdentifier (isMultiple: true)
    Plugins->>Plugins: collect plugin arrays from providers
    Plugins->>Plugins: flatten plugins (plugins.flat())
    ApolloCore->>ApolloServer: toResolvedValue(plugins[][]) -> ApolloServer({ plugins: flattened })
    ApolloServer->>ApolloServer: created and cached (inSingletonScope)
Loading
sequenceDiagram
    participant HTTP as HTTP Server
    participant Container as Inversify Container
    participant WsModule as ApolloSubscriptionServerContainerModule
    participant WsServer as WebSocketServer
    participant GraphQLWs as graphql-ws (useServer)

    HTTP->>Container: load ApolloSubscriptionServerContainerModule(options)
    Container->>WsModule: resolve wsServerServiceIdentifier factory (httpServer, path)
    WsModule->>WsServer: create WebSocketServer(httpServer, { path })
    WsServer->>WsServer: bound as singleton
    WsModule->>GraphQLWs: call useServer(schema, wsServer)
    GraphQLWs->>WsModule: return { drainServer, dispose }
    WsModule->>Container: register Apollo plugin with serverWillStart -> drainServer
    Note over WsModule,GraphQLWs: On shutdown, plugin.drained -> serverCleanup.dispose()
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I flattened arrays to make plugins sing,

Singletons now guard the server ring,
A websocket bridge hops into the stack,
Subscriptions listen, then tidy back,
A rabbit cheers: "DI refactored — hop!" 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'Add apollo subscriptions ws package' directly aligns with the primary changeset objective of introducing a new apollo-subscription-ws package, clearly summarizing the main change.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/add-apollo-subscriptions-ws-package

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between efdacf4 and 0707e31.

📒 Files selected for processing (4)
  • packages/apollo-core/.gitignore
  • packages/apollo-express/.gitignore
  • packages/apollo-subscription-ws/.gitignore
  • packages/codegen/.gitignore
🧰 Additional context used
🧠 Learnings (9)
📚 Learning: 2025-12-19T19:51:35.306Z
Learnt from: notaphplover
Repo: inversify/graphql PR: 6
File: packages/codegen/tsconfig.json:1-10
Timestamp: 2025-12-19T19:51:35.306Z
Learning: In the inversifyjs/graphql-codegen package (packages/codegen/), both tsconfig.json and tsconfig.esm.json exist intentionally, even though they may appear identical. This is part of the planned build strategy.

Applied to files:

  • packages/apollo-subscription-ws/.gitignore
📚 Learning: 2025-12-24T10:31:07.641Z
Learnt from: CR
Repo: inversify/graphql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-24T10:31:07.641Z
Learning: Applies to **/*.spec-d.ts : Name type tests with *.spec-d.ts file extension for TypeScript type checking tests

Applied to files:

  • packages/apollo-subscription-ws/.gitignore
📚 Learning: 2025-12-24T10:31:07.641Z
Learnt from: CR
Repo: inversify/graphql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-24T10:31:07.641Z
Learning: Applies to **/tsconfig*.json : Configure TypeScript with multiple tsconfig files for different output formats (ESM and CommonJS)

Applied to files:

  • packages/apollo-subscription-ws/.gitignore
📚 Learning: 2025-12-24T10:31:07.641Z
Learnt from: CR
Repo: inversify/graphql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-24T10:31:07.641Z
Learning: Applies to **/*.{spec,int.spec,spec-d}.ts : Use Vitest for unit and integration testing with extensive test coverage

Applied to files:

  • packages/apollo-subscription-ws/.gitignore
📚 Learning: 2025-12-24T10:31:07.641Z
Learnt from: CR
Repo: inversify/graphql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-24T10:31:07.641Z
Learning: Applies to **/*.{ts,tsx} : Use strict mode enabled for TypeScript across all packages

Applied to files:

  • packages/apollo-subscription-ws/.gitignore
📚 Learning: 2025-12-24T10:31:07.641Z
Learnt from: CR
Repo: inversify/graphql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-24T10:31:07.641Z
Learning: Use Turbo for task orchestration and caching in monorepo builds

Applied to files:

  • packages/apollo-subscription-ws/.gitignore
  • packages/apollo-core/.gitignore
  • packages/apollo-express/.gitignore
  • packages/codegen/.gitignore
📚 Learning: 2025-12-24T10:31:07.641Z
Learnt from: CR
Repo: inversify/graphql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-24T10:31:07.641Z
Learning: Applies to **/*.spec.ts : Name unit tests with *.spec.ts file extension

Applied to files:

  • packages/apollo-subscription-ws/.gitignore
📚 Learning: 2025-12-24T10:31:07.641Z
Learnt from: CR
Repo: inversify/graphql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-24T10:31:07.641Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use ESLint with shared configuration from inversifyjs/foundation-eslint-config

Applied to files:

  • packages/apollo-subscription-ws/.gitignore
📚 Learning: 2025-12-24T10:31:07.641Z
Learnt from: CR
Repo: inversify/graphql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-24T10:31:07.641Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,md} : Use Prettier with shared configuration from inversifyjs/foundation-prettier-config

Applied to files:

  • packages/apollo-subscription-ws/.gitignore
🔇 Additional comments (4)
packages/apollo-express/.gitignore (1)

16-16: Gitignore pattern correctly anchored to repository root.

The change from .turbo/ to /.turbo/ properly restricts the ignore pattern to the repository root, ensuring Turborepo cache artifacts are ignored at the correct scope.

packages/apollo-core/.gitignore (1)

16-16: Consistent root-anchored Turborepo pattern.

Mirrors the same pattern applied to other packages, ensuring uniform gitignore behavior across the monorepo.

packages/codegen/.gitignore (2)

16-16: Consistent root-anchored Turborepo pattern.

Aligns with changes applied across other packages in the monorepo.


1-16: Inconsistency: PR objectives describe unrelated changes.

The provided files contain only .gitignore updates to Turborepo ignore patterns. However, the PR objectives describe changes to Apollo subscriptions package, plugin service identifiers, and removal of httpServerServiceIdentifier—none of which appear in these files.

Please clarify whether:

  1. These are the only files being reviewed, or
  2. Additional files are missing from the review context.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
packages/apollo-subscription-ws/README.md (1)

1-3: Consider expanding the README with usage documentation.

The current README is quite minimal. Consider adding:

  • Installation instructions
  • Basic usage examples
  • API overview or links to API documentation
  • Integration examples with Apollo Server
packages/apollo-subscription-ws/src/apollo/models/ApolloSubscriptionServerContainerModuleOptions.ts (1)

1-3: Consider adding JSDoc documentation.

While the interface is clear, adding JSDoc comments would improve the developer experience by documenting the purpose of the path property and expected values.

🔎 Proposed documentation enhancement
+/**
+ * Configuration options for the Apollo Subscription Server Container Module.
+ */
 export interface ApolloSubscriptionServerContainerModuleOptions {
+  /**
+   * The path where the WebSocket server will be mounted.
+   * @default '/graphql' (or application default)
+   */
   path?: string;
 }
packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.int.spec.ts (1)

185-201: Consider adding a timeout to prevent test hanging.

If the subscription resolver behavior changes or fails, this test could hang indefinitely waiting for 2 messages. Consider adding a timeout mechanism:

🔎 Optional: Add timeout for robustness
         // Collect subscription results
-        await new Promise<void>((resolve: () => void) => {
+        await new Promise<void>((resolve: () => void, reject: (reason?: unknown) => void) => {
+          const timeout = setTimeout(() => {
+            reject(new Error('Subscription timeout - did not receive expected messages'));
+          }, 5000);
+
           let receivedCount: number = 0;
           wsClient.on('message', (data: Buffer) => {
             const message: { type?: string; payload?: unknown } = JSON.parse(
               data.toString(),
             ) as { type?: string; payload?: unknown };
             if (message.type === 'next') {
               subscriptionResults.push(message.payload);
               receivedCount++;
               if (receivedCount === 2) {
+                clearTimeout(timeout);
                 resolve();
               }
             } else if (message.type === 'complete') {
+              clearTimeout(timeout);
               resolve();
             }
           });
         });
packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.spec.ts (1)

1-10: Type-only import for Mocked type.

The Mocked import is used only as a type annotation. Consider using a type-only import for clarity:

 import {
   afterAll,
   beforeAll,
   describe,
   expect,
   it,
   type Mock,
-  Mocked,
+  type Mocked,
   vitest,
 } from 'vitest';
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c868852 and efdacf4.

📒 Files selected for processing (27)
  • .changeset/fair-vans-strive.md
  • .changeset/perky-eggs-serve.md
  • .changeset/three-shrimps-make.md
  • packages/apollo-core/src/apollo/models/apolloServerPluginsServiceIdentifier.ts
  • packages/apollo-core/src/apollo/modules/ApolloServerContainerModule.spec.ts
  • packages/apollo-core/src/apollo/modules/ApolloServerContainerModule.ts
  • packages/apollo-express/src/apollo/controllers/buildApolloServerExpressController.int.spec.ts
  • packages/apollo-express/src/apollo/models/httpServerServiceIdentifier.ts
  • packages/apollo-express/src/apollo/modules/ApolloExpressServerContainerModule.spec.ts
  • packages/apollo-express/src/apollo/modules/ApolloExpressServerContainerModule.ts
  • packages/apollo-express/src/index.ts
  • packages/apollo-subscription-ws/.gitignore
  • packages/apollo-subscription-ws/.lintstagedrc.json
  • packages/apollo-subscription-ws/.npmignore
  • packages/apollo-subscription-ws/README.md
  • packages/apollo-subscription-ws/eslint.config.mjs
  • packages/apollo-subscription-ws/package.json
  • packages/apollo-subscription-ws/prettier.config.mjs
  • packages/apollo-subscription-ws/src/apollo/models/ApolloSubscriptionServerContainerModuleOptions.ts
  • packages/apollo-subscription-ws/src/apollo/models/wsServerServiceIdentifier.ts
  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.int.spec.ts
  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.spec.ts
  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.ts
  • packages/apollo-subscription-ws/src/index.ts
  • packages/apollo-subscription-ws/tsconfig.esm.json
  • packages/apollo-subscription-ws/tsconfig.json
  • packages/apollo-subscription-ws/vitest.config.mjs
💤 Files with no reviewable changes (2)
  • packages/apollo-express/src/index.ts
  • packages/apollo-express/src/apollo/models/httpServerServiceIdentifier.ts
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use strict mode enabled for TypeScript across all packages

Files:

  • packages/apollo-subscription-ws/src/index.ts
  • packages/apollo-subscription-ws/src/apollo/models/ApolloSubscriptionServerContainerModuleOptions.ts
  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.int.spec.ts
  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.spec.ts
  • packages/apollo-express/src/apollo/modules/ApolloExpressServerContainerModule.ts
  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.ts
  • packages/apollo-core/src/apollo/models/apolloServerPluginsServiceIdentifier.ts
  • packages/apollo-express/src/apollo/modules/ApolloExpressServerContainerModule.spec.ts
  • packages/apollo-core/src/apollo/modules/ApolloServerContainerModule.spec.ts
  • packages/apollo-express/src/apollo/controllers/buildApolloServerExpressController.int.spec.ts
  • packages/apollo-core/src/apollo/modules/ApolloServerContainerModule.ts
  • packages/apollo-subscription-ws/src/apollo/models/wsServerServiceIdentifier.ts
**/*.{ts,tsx,js,jsx,json,md}

📄 CodeRabbit inference engine (AGENTS.md)

Use Prettier with shared configuration from @inversifyjs/foundation-prettier-config

Files:

  • packages/apollo-subscription-ws/src/index.ts
  • packages/apollo-subscription-ws/tsconfig.json
  • packages/apollo-subscription-ws/src/apollo/models/ApolloSubscriptionServerContainerModuleOptions.ts
  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.int.spec.ts
  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.spec.ts
  • packages/apollo-express/src/apollo/modules/ApolloExpressServerContainerModule.ts
  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.ts
  • packages/apollo-subscription-ws/README.md
  • packages/apollo-subscription-ws/package.json
  • packages/apollo-core/src/apollo/models/apolloServerPluginsServiceIdentifier.ts
  • packages/apollo-express/src/apollo/modules/ApolloExpressServerContainerModule.spec.ts
  • packages/apollo-subscription-ws/tsconfig.esm.json
  • packages/apollo-core/src/apollo/modules/ApolloServerContainerModule.spec.ts
  • packages/apollo-express/src/apollo/controllers/buildApolloServerExpressController.int.spec.ts
  • packages/apollo-core/src/apollo/modules/ApolloServerContainerModule.ts
  • packages/apollo-subscription-ws/src/apollo/models/wsServerServiceIdentifier.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use ESLint with shared configuration from @inversifyjs/foundation-eslint-config

Files:

  • packages/apollo-subscription-ws/src/index.ts
  • packages/apollo-subscription-ws/src/apollo/models/ApolloSubscriptionServerContainerModuleOptions.ts
  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.int.spec.ts
  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.spec.ts
  • packages/apollo-express/src/apollo/modules/ApolloExpressServerContainerModule.ts
  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.ts
  • packages/apollo-core/src/apollo/models/apolloServerPluginsServiceIdentifier.ts
  • packages/apollo-express/src/apollo/modules/ApolloExpressServerContainerModule.spec.ts
  • packages/apollo-core/src/apollo/modules/ApolloServerContainerModule.spec.ts
  • packages/apollo-express/src/apollo/controllers/buildApolloServerExpressController.int.spec.ts
  • packages/apollo-core/src/apollo/modules/ApolloServerContainerModule.ts
  • packages/apollo-subscription-ws/src/apollo/models/wsServerServiceIdentifier.ts
**/tsconfig*.json

📄 CodeRabbit inference engine (AGENTS.md)

Configure TypeScript with multiple tsconfig files for different output formats (ESM and CommonJS)

Files:

  • packages/apollo-subscription-ws/tsconfig.json
  • packages/apollo-subscription-ws/tsconfig.esm.json
**/*.{spec,int.spec,spec-d}.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{spec,int.spec,spec-d}.ts: Use Vitest for unit and integration testing with extensive test coverage
Mock external modules using vitest.fn() and vitest.mock() in tests

Files:

  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.int.spec.ts
  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.spec.ts
  • packages/apollo-express/src/apollo/modules/ApolloExpressServerContainerModule.spec.ts
  • packages/apollo-core/src/apollo/modules/ApolloServerContainerModule.spec.ts
  • packages/apollo-express/src/apollo/controllers/buildApolloServerExpressController.int.spec.ts
**/*.spec.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name unit tests with *.spec.ts file extension

Files:

  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.int.spec.ts
  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.spec.ts
  • packages/apollo-express/src/apollo/modules/ApolloExpressServerContainerModule.spec.ts
  • packages/apollo-core/src/apollo/modules/ApolloServerContainerModule.spec.ts
  • packages/apollo-express/src/apollo/controllers/buildApolloServerExpressController.int.spec.ts
**/*.int.spec.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name integration tests with *.int.spec.ts file extension

Files:

  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.int.spec.ts
  • packages/apollo-express/src/apollo/controllers/buildApolloServerExpressController.int.spec.ts
**/*.{spec,int.spec}.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{spec,int.spec}.ts: Organize test describe blocks in four-layer structure: Class → Method → Input → Flow scopes
Use descriptive test names with 'when called, and [condition]' pattern

Files:

  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.int.spec.ts
  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.spec.ts
  • packages/apollo-express/src/apollo/modules/ApolloExpressServerContainerModule.spec.ts
  • packages/apollo-core/src/apollo/modules/ApolloServerContainerModule.spec.ts
  • packages/apollo-express/src/apollo/controllers/buildApolloServerExpressController.int.spec.ts
**/package.json

📄 CodeRabbit inference engine (AGENTS.md)

**/package.json: Use workspace protocol (workspace:*) for internal dependencies in package.json
Pin development dependencies to specific versions for security and reproducibility

Files:

  • packages/apollo-subscription-ws/package.json
🧠 Learnings (13)
📚 Learning: 2025-12-24T10:31:07.641Z
Learnt from: CR
Repo: inversify/graphql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-24T10:31:07.641Z
Learning: Applies to **/*.{spec,int.spec,spec-d}.ts : Use Vitest for unit and integration testing with extensive test coverage

Applied to files:

  • packages/apollo-subscription-ws/vitest.config.mjs
  • packages/apollo-subscription-ws/tsconfig.json
  • packages/apollo-subscription-ws/.npmignore
  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.int.spec.ts
  • packages/apollo-subscription-ws/.lintstagedrc.json
  • packages/apollo-express/src/apollo/modules/ApolloExpressServerContainerModule.spec.ts
  • packages/apollo-subscription-ws/tsconfig.esm.json
  • packages/apollo-subscription-ws/.gitignore
  • packages/apollo-core/src/apollo/modules/ApolloServerContainerModule.spec.ts
📚 Learning: 2025-12-24T10:31:07.641Z
Learnt from: CR
Repo: inversify/graphql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-24T10:31:07.641Z
Learning: Applies to **/*.{spec,int.spec,spec-d}.ts : Mock external modules using vitest.fn() and vitest.mock() in tests

Applied to files:

  • packages/apollo-subscription-ws/vitest.config.mjs
  • packages/apollo-subscription-ws/.npmignore
  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.int.spec.ts
  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.spec.ts
  • packages/apollo-express/src/apollo/modules/ApolloExpressServerContainerModule.spec.ts
  • packages/apollo-core/src/apollo/modules/ApolloServerContainerModule.spec.ts
📚 Learning: 2025-12-24T10:31:07.641Z
Learnt from: CR
Repo: inversify/graphql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-24T10:31:07.641Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use ESLint with shared configuration from inversifyjs/foundation-eslint-config

Applied to files:

  • packages/apollo-subscription-ws/vitest.config.mjs
  • packages/apollo-subscription-ws/prettier.config.mjs
  • packages/apollo-subscription-ws/tsconfig.json
  • packages/apollo-subscription-ws/.npmignore
  • packages/apollo-subscription-ws/.lintstagedrc.json
  • packages/apollo-subscription-ws/tsconfig.esm.json
  • packages/apollo-subscription-ws/.gitignore
  • packages/apollo-subscription-ws/eslint.config.mjs
📚 Learning: 2025-12-24T10:31:07.641Z
Learnt from: CR
Repo: inversify/graphql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-24T10:31:07.641Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,md} : Use Prettier with shared configuration from inversifyjs/foundation-prettier-config

Applied to files:

  • packages/apollo-subscription-ws/vitest.config.mjs
  • packages/apollo-subscription-ws/prettier.config.mjs
  • packages/apollo-subscription-ws/tsconfig.json
  • packages/apollo-subscription-ws/.npmignore
  • packages/apollo-subscription-ws/.lintstagedrc.json
  • packages/apollo-subscription-ws/tsconfig.esm.json
  • packages/apollo-subscription-ws/.gitignore
  • packages/apollo-subscription-ws/eslint.config.mjs
📚 Learning: 2025-12-19T19:51:35.306Z
Learnt from: notaphplover
Repo: inversify/graphql PR: 6
File: packages/codegen/tsconfig.json:1-10
Timestamp: 2025-12-19T19:51:35.306Z
Learning: In the inversifyjs/graphql-codegen package (packages/codegen/), both tsconfig.json and tsconfig.esm.json exist intentionally, even though they may appear identical. This is part of the planned build strategy.

Applied to files:

  • packages/apollo-subscription-ws/prettier.config.mjs
  • packages/apollo-subscription-ws/tsconfig.json
  • packages/apollo-subscription-ws/.npmignore
  • packages/apollo-subscription-ws/package.json
  • packages/apollo-subscription-ws/tsconfig.esm.json
  • packages/apollo-subscription-ws/.gitignore
  • packages/apollo-subscription-ws/eslint.config.mjs
📚 Learning: 2025-12-24T10:31:07.641Z
Learnt from: CR
Repo: inversify/graphql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-24T10:31:07.641Z
Learning: Applies to **/tsconfig*.json : Configure TypeScript with multiple tsconfig files for different output formats (ESM and CommonJS)

Applied to files:

  • packages/apollo-subscription-ws/tsconfig.json
  • packages/apollo-subscription-ws/.npmignore
  • packages/apollo-subscription-ws/.lintstagedrc.json
  • packages/apollo-subscription-ws/tsconfig.esm.json
  • packages/apollo-subscription-ws/.gitignore
📚 Learning: 2025-12-24T10:31:07.641Z
Learnt from: CR
Repo: inversify/graphql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-24T10:31:07.641Z
Learning: Applies to **/*.{ts,tsx} : Use strict mode enabled for TypeScript across all packages

Applied to files:

  • packages/apollo-subscription-ws/tsconfig.json
  • packages/apollo-subscription-ws/.npmignore
  • packages/apollo-subscription-ws/.lintstagedrc.json
  • packages/apollo-subscription-ws/tsconfig.esm.json
  • packages/apollo-subscription-ws/.gitignore
📚 Learning: 2025-12-24T10:31:07.641Z
Learnt from: CR
Repo: inversify/graphql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-24T10:31:07.641Z
Learning: Applies to **/*.spec-d.ts : Name type tests with *.spec-d.ts file extension for TypeScript type checking tests

Applied to files:

  • packages/apollo-subscription-ws/.npmignore
  • packages/apollo-subscription-ws/.lintstagedrc.json
  • packages/apollo-subscription-ws/.gitignore
📚 Learning: 2025-12-24T10:31:07.641Z
Learnt from: CR
Repo: inversify/graphql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-24T10:31:07.641Z
Learning: Applies to **/*.spec.ts : Name unit tests with *.spec.ts file extension

Applied to files:

  • packages/apollo-subscription-ws/.npmignore
  • packages/apollo-subscription-ws/.lintstagedrc.json
  • packages/apollo-subscription-ws/.gitignore
📚 Learning: 2025-12-24T10:31:07.641Z
Learnt from: CR
Repo: inversify/graphql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-24T10:31:07.641Z
Learning: Applies to **/*.int.spec.ts : Name integration tests with *.int.spec.ts file extension

Applied to files:

  • packages/apollo-subscription-ws/.npmignore
  • packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.int.spec.ts
📚 Learning: 2025-12-24T10:31:07.641Z
Learnt from: CR
Repo: inversify/graphql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-24T10:31:07.641Z
Learning: Applies to **/*.{spec,int.spec}.ts : Organize test describe blocks in four-layer structure: Class → Method → Input → Flow scopes

Applied to files:

  • packages/apollo-subscription-ws/.npmignore
  • packages/apollo-express/src/apollo/modules/ApolloExpressServerContainerModule.spec.ts
📚 Learning: 2025-12-24T10:31:07.641Z
Learnt from: CR
Repo: inversify/graphql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-24T10:31:07.641Z
Learning: Applies to **/package.json : Use workspace protocol (workspace:*) for internal dependencies in package.json

Applied to files:

  • packages/apollo-subscription-ws/package.json
📚 Learning: 2025-12-24T10:31:07.641Z
Learnt from: CR
Repo: inversify/graphql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-24T10:31:07.641Z
Learning: Use Turbo for task orchestration and caching in monorepo builds

Applied to files:

  • packages/apollo-subscription-ws/.gitignore
🧬 Code graph analysis (4)
packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.int.spec.ts (3)
packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.ts (1)
  • ApolloSubscriptionServerContainerModule (17-62)
packages/apollo-express/src/apollo/modules/ApolloExpressServerContainerModule.ts (1)
  • ApolloExpressServerContainerModule (20-64)
packages/apollo-subscription-ws/src/apollo/models/wsServerServiceIdentifier.ts (1)
  • wsServerServiceIdentifier (4-5)
packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.spec.ts (4)
packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.ts (1)
  • ApolloSubscriptionServerContainerModule (17-62)
packages/apollo-subscription-ws/src/index.ts (3)
  • ApolloSubscriptionServerContainerModule (2-2)
  • wsServerServiceIdentifier (3-3)
  • ApolloSubscriptionServerContainerModuleOptions (1-1)
packages/apollo-subscription-ws/src/apollo/models/wsServerServiceIdentifier.ts (1)
  • wsServerServiceIdentifier (4-5)
packages/apollo-subscription-ws/src/apollo/models/ApolloSubscriptionServerContainerModuleOptions.ts (1)
  • ApolloSubscriptionServerContainerModuleOptions (1-3)
packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.ts (2)
packages/apollo-subscription-ws/src/apollo/models/ApolloSubscriptionServerContainerModuleOptions.ts (1)
  • ApolloSubscriptionServerContainerModuleOptions (1-3)
packages/apollo-subscription-ws/src/apollo/models/wsServerServiceIdentifier.ts (1)
  • wsServerServiceIdentifier (4-5)
packages/apollo-subscription-ws/src/apollo/models/wsServerServiceIdentifier.ts (1)
packages/apollo-subscription-ws/src/index.ts (1)
  • wsServerServiceIdentifier (3-3)
🔇 Additional comments (28)
packages/apollo-subscription-ws/.npmignore (1)

1-16: Standard npm package publishing configuration—approved.

The .npmignore file follows npm package best practices, correctly excluding source code, test artifacts, build tooling, and configuration files while implicitly preserving built outputs and essential runtime files (package.json, README, etc.).

packages/apollo-express/src/apollo/controllers/buildApolloServerExpressController.int.spec.ts (1)

5-20: LGTM! Proper use of type-only imports.

The refactoring correctly applies type-only imports for symbols used exclusively in type positions (BaseContext, ExpressContextFunctionArgument, ApolloServerController, express, ContainerModuleLoadOptions, Newable), while appropriately keeping Container as a value import since it's instantiated on line 56. This improves tree-shaking and follows TypeScript best practices.

.changeset/fair-vans-strive.md (1)

1-5: LGTM!

The changeset correctly documents the removal of httpServerServiceIdentifier from the public API with an appropriate minor version bump.

packages/apollo-subscription-ws/.lintstagedrc.json (1)

1-9: LGTM!

The lint-staged configuration correctly formats JavaScript files with Prettier and TypeScript files with both Prettier and ESLint, following the project's conventions.

.changeset/three-shrimps-make.md (1)

1-5: LGTM!

The changeset accurately documents the update to apolloServerPluginsServiceIdentifier as a plugin array service identifier with an appropriate minor version bump.

packages/apollo-subscription-ws/tsconfig.json (1)

1-10: LGTM!

The TypeScript configuration correctly extends the foundation base ESM config and sets up standard output directories for the build process.

packages/apollo-subscription-ws/tsconfig.esm.json (1)

1-10: LGTM!

The ESM TypeScript configuration correctly extends the foundation base config. Note that having both tsconfig.json and tsconfig.esm.json with similar configurations is intentional and part of the build strategy.

Based on learnings, multiple tsconfig files for different output formats is an expected pattern in this repository.

packages/apollo-subscription-ws/eslint.config.mjs (1)

1-3: LGTM!

The ESLint configuration correctly uses the shared foundation config by importing and spreading buildDefaultConfig(), following the project's established pattern.

Based on learnings, this aligns with using ESLint with shared configuration from @inversifyjs/foundation-eslint-config.

packages/apollo-subscription-ws/vitest.config.mjs (1)

1-3: LGTM!

The Vitest configuration correctly re-exports the shared foundation test config, maintaining consistency with the project's testing setup.

Based on learnings, this aligns with using Vitest for unit and integration testing with the shared foundation configuration.

packages/apollo-subscription-ws/prettier.config.mjs (1)

1-3: LGTM!

The Prettier configuration follows the standard pattern of re-exporting from the foundation config, consistent with the coding guidelines.

packages/apollo-subscription-ws/package.json (2)

1-73: Package configuration looks good.

The package.json follows the coding guidelines:

  • Uses workspace protocol for internal dependencies (@inversifyjs/apollo-core)
  • Pins all dev dependencies to specific versions
  • Proper exports and module configuration
  • Comprehensive scripts for build, test, and formatting

8-9: All dependencies are correctly configured and compatible.

[email protected] is a valid stable release with peer dependency ws@^8, which is satisfied by the specified ws@^8.18.3. All devDependencies are properly pinned to specific versions, and workspace protocol is correctly applied to internal dependencies per coding guidelines.

.changeset/perky-eggs-serve.md (1)

1-6: LGTM!

The changeset correctly documents the minor version bump and the two new public exports for the apollo-subscription-ws package.

packages/apollo-express/src/apollo/modules/ApolloExpressServerContainerModule.ts (3)

28-30: LGTM!

Adding inSingletonScope() to the controller binding ensures the controller is instantiated once, which is appropriate for this use case.


33-41: LGTM!

Adding inSingletonScope() to the HTTP server binding ensures a single server instance is created and reused, which is the correct behavior for server lifecycle management.


43-52: LGTM!

Adding inSingletonScope() to the Apollo server plugins binding ensures plugins are initialized once, which is appropriate for plugin lifecycle management.

packages/apollo-subscription-ws/src/apollo/models/wsServerServiceIdentifier.ts (1)

1-5: LGTM!

The service identifier is correctly defined using Symbol.for() with appropriate typing. The symbol string follows the package naming convention and enables proper dependency injection for the WebSocket server.

packages/apollo-express/src/apollo/modules/ApolloExpressServerContainerModule.spec.ts (2)

79-99: LGTM!

The mock setup correctly supports method chaining for the fluent binding syntax, with toResolvedValue and toSelf returning this to enable .inSingletonScope() chaining.


177-182: LGTM!

The test correctly verifies that inSingletonScope() is called 5 times, matching the expected bindings with singleton scope (3 in ApolloExpressServerContainerModule + 2 from parent ApolloServerContainerModule).

packages/apollo-subscription-ws/src/index.ts (1)

1-3: LGTM!

The public API exports are well-defined, exposing the necessary types, class, and service identifier for consumers of the apollo-subscription-ws package. The use of .js extensions is correct for ESM modules.

packages/apollo-core/src/apollo/models/apolloServerPluginsServiceIdentifier.ts (1)

4-7: Type signature update aligns with multi-provider binding pattern.

The removal of | undefined from the service identifier type correctly reflects the new isMultiple: true binding strategy, where the container always returns an array (empty if no bindings exist). This is a coherent change with the DI wiring updates in ApolloServerContainerModule.

packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.ts (1)

17-61: Well-structured container module for WebSocket subscriptions.

The module correctly:

  1. Binds the WebSocketServer with proper dependency on httpServerServiceIdentifier
  2. Configures the Apollo plugin with useServer from graphql-ws
  3. Implements proper cleanup via the drainServer lifecycle hook

The singleton scope is appropriate for both bindings to ensure consistent server instances.

packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.int.spec.ts (1)

97-100: Consider closing WebSocket server before HTTP server.

The WebSocket server depends on the HTTP server. Closing the HTTP server first may leave the WebSocket server in an inconsistent state momentarily. Consider reversing the order:

     afterAll(() => {
       wsServer.close();
       httpServer.close();
     });

Since wsServer.close() is already called first, this is actually correct. No change needed.

packages/apollo-subscription-ws/src/apollo/modules/ApolloSubscriptionServerContainerModule.spec.ts (1)

34-282: Comprehensive unit test coverage.

The test suite thoroughly covers:

  • Module instantiation with and without options
  • DI binding chain verification (bind → toResolvedValue → inSingletonScope)
  • Resolver function behavior for both wsServer and plugins
  • Plugin lifecycle hooks (serverWillStart, drainServer)
  • Cleanup disposal verification

Good use of captured resolver functions to test internal behavior.

packages/apollo-core/src/apollo/modules/ApolloServerContainerModule.spec.ts (3)

38-49: Mock type simplification and fluent chain support.

Good refactoring: the simplified mock type with explicit inSingletonScope and toResolvedValue properties is cleaner and more focused than using the full BindToFluentSyntax type. The .mockReturnThis() correctly enables the fluent .inSingletonScope() chain.


87-97: Assertion updated for multi-provider binding pattern.

The expectation correctly verifies isMultiple: true configuration for the plugins service identifier, aligning with the implementation change from optional single-value to multi-value binding.


99-106: New singleton scope verification test.

Good addition to verify that both bindings correctly apply singleton scope.

packages/apollo-core/src/apollo/modules/ApolloServerContainerModule.ts (1)

29-55: Multi-provider plugin pattern with singleton scope.

The refactoring from optional single-value to multi-value binding (isMultiple: true) enables multiple container modules to contribute plugins independently. The plugins.flat() correctly merges all plugin arrays from different providers.

Singleton scope for both the GraphQL schema and ApolloServer ensures consistent instances throughout the application lifecycle.

@notaphplover notaphplover merged commit 58bb344 into master Dec 24, 2025
7 checks passed
@notaphplover notaphplover deleted the chore/add-apollo-subscriptions-ws-package branch December 24, 2025 16:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants