Skip to content

Commit 047eafc

Browse files
committed
Update task link service to new typed event emitter
1 parent 43b0c29 commit 047eafc

File tree

7 files changed

+49
-58
lines changed

7 files changed

+49
-58
lines changed

apps/array/src/main/di/container.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import { FsService } from "../services/fs/service.js";
1010
import { GitService } from "../services/git/service.js";
1111
import { OAuthService } from "../services/oauth/service.js";
1212
import { ShellService } from "../services/shell/service.js";
13+
import { TaskLinkService } from "../services/task-link/service.js";
1314
import { UpdatesService } from "../services/updates/service.js";
1415
import { MAIN_TOKENS } from "./tokens.js";
15-
import { TaskLinkService } from "../services/task-link/service.js";
1616

1717
export const container = new Container({
1818
defaultScope: "Singleton",
@@ -29,4 +29,4 @@ container.bind(MAIN_TOKENS.GitService).to(GitService);
2929
container.bind(MAIN_TOKENS.OAuthService).to(OAuthService);
3030
container.bind(MAIN_TOKENS.ShellService).to(ShellService);
3131
container.bind(MAIN_TOKENS.UpdatesService).to(UpdatesService);
32-
container.bind(MAIN_TOKENS.TaskLinkService).to(TaskLinkService);
32+
container.bind(MAIN_TOKENS.TaskLinkService).to(TaskLinkService);

apps/array/src/main/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ import {
4343
shutdownPostHog,
4444
trackAppEvent,
4545
} from "./services/posthog-analytics.js";
46+
import type { TaskLinkService } from "./services/task-link/service";
4647
import type { UpdatesService } from "./services/updates/service.js";
4748
import { registerWorkspaceIpc } from "./services/workspace/index.js";
48-
import { TaskLinkService } from "./services/task-link/service";
4949

5050
const __filename = fileURLToPath(import.meta.url);
5151
const __dirname = path.dirname(__filename);

apps/array/src/main/services/deep-link/service.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export class DeepLinkService {
5252

5353
/**
5454
* Handle an incoming deep link URL
55-
*
55+
*
5656
* NOTE: Strips the protocol and main key, passing only dynamic segments to handlers.
5757
*/
5858
public handleUrl(url: string): boolean {
@@ -83,7 +83,9 @@ export class DeepLinkService {
8383
// Extract path segments after the main key (strip leading slash)
8484
const pathSegments = parsedUrl.pathname.slice(1);
8585

86-
log.info(`Routing deep link to '${mainKey}' handler with path: ${pathSegments || "(empty)"}`);
86+
log.info(
87+
`Routing deep link to '${mainKey}' handler with path: ${pathSegments || "(empty)"}`,
88+
);
8789
return handler(pathSegments, parsedUrl.searchParams);
8890
} catch (error) {
8991
log.error("Failed to parse deep link URL:", error);

apps/array/src/main/services/oauth/service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ export class OAuthService {
5252
private readonly deepLinkService: DeepLinkService,
5353
) {
5454
// Register OAuth callback handler for deep links
55-
this.deepLinkService.registerHandler("callback", (url) =>
56-
this.handleOAuthCallback(url),
55+
this.deepLinkService.registerHandler("callback", (_path, searchParams) =>
56+
this.handleOAuthCallback(searchParams),
5757
);
5858
log.info("Registered OAuth callback handler for deep links");
5959
}

apps/array/src/main/services/task-link/service.ts

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,32 @@
1-
import { EventEmitter } from "node:events";
2-
import { injectable } from "inversify";
1+
import { inject, injectable } from "inversify";
2+
import { MAIN_TOKENS } from "../../di/tokens.js";
33
import { logger } from "../../lib/logger.js";
4+
import { TypedEventEmitter } from "../../lib/typed-event-emitter.js";
45
import { getMainWindow } from "../../trpc/context.js";
5-
import type { DeepLinkHandler } from "../deep-link/service.js";
6+
import type { DeepLinkService } from "../deep-link/service.js";
67

78
const log = logger.scope("task-link-service");
89

9-
@injectable()
10-
export class TaskLinkService {
11-
private emitter = new EventEmitter();
12-
13-
/**
14-
* Get the deep link handler for task links.
15-
* Register this with DeepLinkService for the "task" key.
16-
* Expects URLs like: array://task/{taskId}
17-
*/
18-
public getDeepLinkHandler(): DeepLinkHandler {
19-
return (path) => this.handleTaskLink(path);
20-
}
10+
export const TaskLinkEvent = {
11+
OpenTask: "openTask",
12+
} as const;
2113

22-
/**
23-
* Subscribe to task link events.
24-
*/
25-
public onTaskLink(callback: (taskId: string) => void): () => void {
26-
this.emitter.on("task", callback);
27-
return () => this.emitter.off("task", callback);
14+
export interface TaskLinkEvents {
15+
[TaskLinkEvent.OpenTask]: { taskId: string };
16+
}
17+
18+
@injectable()
19+
export class TaskLinkService extends TypedEventEmitter<TaskLinkEvents> {
20+
constructor(
21+
@inject(MAIN_TOKENS.DeepLinkService)
22+
private readonly deepLinkService: DeepLinkService,
23+
) {
24+
super();
25+
// Register task link handler for deep links
26+
this.deepLinkService.registerHandler("task", (path) =>
27+
this.handleTaskLink(path),
28+
);
29+
log.info("Registered task link handler for deep links");
2830
}
2931

3032
private handleTaskLink(path: string): boolean {
@@ -37,7 +39,7 @@ export class TaskLinkService {
3739
}
3840

3941
log.info(`Emitting task link event: ${taskId}`);
40-
this.emitter.emit("task", taskId);
42+
this.emit(TaskLinkEvent.OpenTask, { taskId });
4143

4244
// Focus the window
4345
const mainWindow = getMainWindow();

apps/array/src/main/trpc/router.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { deepLinkRouter } from "./routers/deep-link.js";
21
import { contextMenuRouter } from "./routers/context-menu.js";
2+
import { deepLinkRouter } from "./routers/deep-link.js";
33
import { dockBadgeRouter } from "./routers/dock-badge.js";
44
import { encryptionRouter } from "./routers/encryption.js";
55
import { externalAppsRouter } from "./routers/external-apps.js";
Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,26 @@
1-
import { get } from "../../di/container.js";
1+
import { on } from "node:events";
2+
import { container } from "../../di/container.js";
23
import { MAIN_TOKENS } from "../../di/tokens.js";
3-
import type { TaskLinkService } from "../../services/task-link/service.js";
4+
import {
5+
TaskLinkEvent,
6+
type TaskLinkEvents,
7+
type TaskLinkService,
8+
} from "../../services/task-link/service.js";
49
import { publicProcedure, router } from "../trpc.js";
510

11+
const getService = () =>
12+
container.get<TaskLinkService>(MAIN_TOKENS.TaskLinkService);
13+
614
export const deepLinkRouter = router({
715
/**
816
* Subscribe to task link deep link events.
917
* Emits task ID when array://task/{taskId} is opened.
1018
*/
11-
onOpenTask: publicProcedure.subscription(async function* () {
12-
const taskLinkService = get<TaskLinkService>(MAIN_TOKENS.TaskLinkService);
13-
14-
// Create a queue to buffer events
15-
const queue: string[] = [];
16-
let resolve: (() => void) | null = null;
17-
18-
const unsubscribe = taskLinkService.onTaskLink((taskId) => {
19-
queue.push(taskId);
20-
resolve?.();
21-
});
22-
23-
try {
24-
while (true) {
25-
if (queue.length === 0) {
26-
await new Promise<void>((r) => {
27-
resolve = r;
28-
});
29-
}
30-
const taskId = queue.shift();
31-
if (taskId) {
32-
yield taskId;
33-
}
34-
}
35-
} finally {
36-
unsubscribe();
19+
onOpenTask: publicProcedure.subscription(async function* (opts) {
20+
const service = getService();
21+
const options = opts.signal ? { signal: opts.signal } : undefined;
22+
for await (const [payload] of on(service, TaskLinkEvent.OpenTask, options)) {
23+
yield payload as TaskLinkEvents[typeof TaskLinkEvent.OpenTask];
3724
}
3825
}),
3926
});

0 commit comments

Comments
 (0)