Skip to content

Commit 0397797

Browse files
chore: emit export related events on ExportsManager instance
1 parent f16128c commit 0397797

File tree

4 files changed

+16
-11
lines changed

4 files changed

+16
-11
lines changed

src/common/session.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ export type SessionEvents = {
2525
close: [];
2626
disconnect: [];
2727
"connection-error": [string];
28-
"export-expired": [string];
29-
"export-available": [string];
3028
};
3129

3230
export class Session extends EventEmitter<SessionEvents> {

src/common/sessionExportsManager.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import z from "zod";
22
import path from "path";
33
import fs from "fs/promises";
4+
import EventEmitter from "events";
45
import { createWriteStream } from "fs";
56
import { lock } from "proper-lockfile";
67
import { FindCursor } from "mongodb";
@@ -28,7 +29,12 @@ export type SessionExportsManagerConfig = Pick<
2829

2930
const MAX_LOCK_RETRIES = 10;
3031

31-
export class SessionExportsManager {
32+
type SessionExportsManagerEvents = {
33+
"export-expired": [string];
34+
"export-available": [string];
35+
};
36+
37+
export class SessionExportsManager extends EventEmitter<SessionExportsManagerEvents> {
3238
private availableExports: Export[] = [];
3339
private exportsCleanupInterval: NodeJS.Timeout;
3440
private exportsCleanupInProgress: boolean = false;
@@ -37,6 +43,7 @@ export class SessionExportsManager {
3743
private readonly session: Session,
3844
private readonly config: SessionExportsManagerConfig
3945
) {
46+
super();
4047
this.exportsCleanupInterval = setInterval(
4148
() => void this.cleanupExpiredExports(),
4249
this.config.exportCleanupIntervalMs
@@ -149,7 +156,7 @@ export class SessionExportsManager {
149156
uri: resourceURI,
150157
},
151158
];
152-
this.session.emit("export-available", resourceURI);
159+
this.emit("export-available", resourceURI);
153160
}
154161
}
155162
});
@@ -212,7 +219,7 @@ export class SessionExportsManager {
212219
if (await this.isExportFileExpired(exportPath)) {
213220
await fs.unlink(exportPath);
214221
this.availableExports = this.availableExports.filter(({ name }) => name !== exportName);
215-
this.session.emit("export-expired", this.exportNameToResourceURI(exportName));
222+
this.emit("export-expired", this.exportNameToResourceURI(exportName));
216223
}
217224
}
218225
});

src/resources/common/exportedData.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ export class ExportedData {
1313
private readonly uri = "exported-data://{exportName}";
1414

1515
constructor(private readonly server: Server) {
16-
this.server.session.on("export-available", (uri) => {
16+
this.server.exportsManager.on("export-available", (uri) => {
1717
this.server.mcpServer.sendResourceListChanged();
1818
void this.server.mcpServer.server.sendResourceUpdated({
1919
uri,
2020
});
2121
});
22-
this.server.session.on("export-expired", () => {
22+
this.server.exportsManager.on("export-expired", () => {
2323
this.server.mcpServer.sendResourceListChanged();
2424
});
2525
}

tests/unit/common/sessionExportsManager.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ describe("SessionExportsManager integration test", () => {
152152
it("should create an empty export", async () => {
153153
inputCursor = createDummyFindCursor([]);
154154

155-
const emitSpy = vi.spyOn(session, "emit");
155+
const emitSpy = vi.spyOn(manager, "emit");
156156
await manager.createJSONExport({
157157
input: inputCursor,
158158
exportName,
@@ -183,7 +183,7 @@ describe("SessionExportsManager integration test", () => {
183183
{ cond: "when exportName contains extension", exportName: `foo.bar.${Date.now()}.json` },
184184
])("$cond", ({ exportName }) => {
185185
it("should export relaxed json, update available exports and emit export-available event", async () => {
186-
const emitSpy = vi.spyOn(session, "emit");
186+
const emitSpy = vi.spyOn(manager, "emit");
187187
await manager.createJSONExport({
188188
input: inputCursor,
189189
exportName,
@@ -216,7 +216,7 @@ describe("SessionExportsManager integration test", () => {
216216
{ cond: "when exportName contains extension", exportName: `foo.bar.${Date.now()}.json` },
217217
])("$cond", ({ exportName }) => {
218218
it("should export canonical json, update available exports and emit export-available event", async () => {
219-
const emitSpy = vi.spyOn(session, "emit");
219+
const emitSpy = vi.spyOn(manager, "emit");
220220
await manager.createJSONExport({
221221
input: inputCursor,
222222
exportName,
@@ -250,7 +250,7 @@ describe("SessionExportsManager integration test", () => {
250250

251251
describe("when transform stream throws an error", () => {
252252
it("should remove the partial export and never make it available", async () => {
253-
const emitSpy = vi.spyOn(session, "emit");
253+
const emitSpy = vi.spyOn(manager, "emit");
254254
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
255255
(manager as any).docToEJSONStream = function (ejsonOptions: EJSONOptions | undefined) {
256256
let docsTransformed = 0;

0 commit comments

Comments
 (0)