Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
jannis-baum committed Jul 30, 2024
1 parent bd4ceec commit 0feb7c4
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 29 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"dependencies": {
"@viz-js/viz": "^3.7.0",
"ansi_up": "^6.0.2",
"async-mutex": "^0.5.0",
"axios": "^1.7.2",
"express": "^4.19.2",
"glob": "10.4.5",
Expand Down
2 changes: 1 addition & 1 deletion src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ app.use('/_open', openRouter);
const server = createServer(app);

let shutdownTimer: NodeJS.Timeout | null = null;
export const { clientsAt, messageClients, queueMessage, deleteQueuedMessage } = setupSockets(
export const { clientsAt, messageClients, openAndMessage } = setupSockets(
server,
() => {
if (config.timeout > 0)
Expand Down
14 changes: 9 additions & 5 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,15 @@ const openTarget = async (target: string) => {
}

const resolvedPath = presolve(path);
await axios.post(`${address}/_open`, {
path: resolvedPath,
command: line !== undefined ? 'SCROLL' : undefined,
value: line,
});
try {
await axios.post(`${address}/_open`, {
path: resolvedPath,
command: line !== undefined ? 'SCROLL' : undefined,
value: line,
});
} catch {
console.log(`Failed to open ${target}`);
}
};

export const handleArgs = async () => {
Expand Down
21 changes: 8 additions & 13 deletions src/routes/_open.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Request, Response, Router } from 'express';
import { deleteQueuedMessage, queueMessage } from '../app.js';
import { openAndMessage } from '../app.js';
import { address } from '../cli.js';
import { pathToURL, preferredPath } from '../utils/path.js';
import open from 'open';
Expand All @@ -15,20 +15,15 @@ router.post('/', async (req: Request, res: Response) => {
return;
}

// NOTE: if we ever want to properly consider having many clients to one
// server (currently not smart because entire file system would be
// exposed), we will have to protect this critical section between here and
// the websocket of the client connecting in `src/sockets.ts`
if (command) {
queueMessage(path, `${command}: ${value}`);
} else {
deleteQueuedMessage(path);
}

try {
await open(`${address}${pathToURL(preferredPath(path))}`);
if (command) {
await openAndMessage(path, `${command}: ${value}`);
} else {
await open(`${address}${pathToURL(preferredPath(path))}`);
}
} catch {
deleteQueuedMessage(path);
res.status(500).end();
return;
}

res.end();
Expand Down
33 changes: 24 additions & 9 deletions src/sockets.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { WebSocketServer, WebSocket } from 'ws';
import { v4 as uuidv4 } from 'uuid';
import { Server } from 'http';
import { Mutex, MutexInterface, withTimeout } from 'async-mutex';
import open from 'open';
import { address } from './cli.js';
import { pathToURL, preferredPath } from './utils/path.js';

interface SocketData {
socket: WebSocket;
Expand All @@ -13,8 +17,8 @@ export function setupSockets(server: Server, onNoClients: () => void, onFirstCli

const wss = new WebSocketServer({ server });
const sockets = new Map<string, SocketData>();
// queue of initial message to be sent to new clients
const messageQueue = new Map<string, string>();
// queue of messages to be sent to clients after they have connected
const openQueue = new Map<string, { message: string; mutex: MutexInterface }>();

const terminateSocket = (id: string) => {
const socket = sockets.get(id);
Expand Down Expand Up @@ -46,10 +50,11 @@ export function setupSockets(server: Server, onNoClients: () => void, onFirstCli
switch (key) {
case 'PATH':
sockets.get(id)!.path = value;
const message = messageQueue.get(value);
if (message) {
messageQueue.delete(value);
socket.send(message);
const item = openQueue.get(value);
if (item) {
socket.send(item.message);
item.mutex.release();
openQueue.delete(value);
}
break;
}
Expand Down Expand Up @@ -77,8 +82,18 @@ export function setupSockets(server: Server, onNoClients: () => void, onFirstCli
const messageClients = (clients: SocketData[], message: string) =>
clients.forEach(({ socket }) => socket.send(message));

const queueMessage = (path: string, message: string) => messageQueue.set(path, message);
const deleteQueuedMessage = (path: string) => messageQueue.delete(path);
const openAndMessage = async (path: string, message: string) => {
const item = openQueue.get(path);
if (item) {
await item.mutex.acquire();
}
// need to somehow reuse mutex because when multiple requests are
// waiting for it it won't be released a second time
const mutex = withTimeout(new Mutex(), 3000);
mutex.acquire();
openQueue.set(path, { message, mutex });
await open(`${address}${pathToURL(preferredPath(path))}`);
};

return { clientsAt, messageClients, queueMessage, deleteQueuedMessage };
return { clientsAt, messageClients, openAndMessage };
}
9 changes: 8 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,13 @@ array-union@^2.1.0:
resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==

async-mutex@^0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.5.0.tgz#353c69a0b9e75250971a64ac203b0ebfddd75482"
integrity sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==
dependencies:
tslib "^2.4.0"

asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
Expand Down Expand Up @@ -2598,7 +2605,7 @@ ts-node@^10.9.2:
v8-compile-cache-lib "^3.0.1"
yn "3.1.1"

tslib@^2.6.2:
tslib@^2.4.0, tslib@^2.6.2:
version "2.6.3"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0"
integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==
Expand Down

0 comments on commit 0feb7c4

Please sign in to comment.