Files
backnotprop__plannotator/apps/pi-extension/server/annotations.ts
Devinda Senanayaka 929e8f9f59 perf(pi-extension): use exact .ts relative specifiers (#1106)
The Pi extension is distributed and executed as raw TypeScript through
Pi's jiti loader. Phantom .js paths force jiti through its last-resort
fallback, while extensionless paths still require probing. Exact .ts
paths avoid both and match the files that actually ship.

- rewrite relative .js and extensionless specifiers in hand-written
  sources (the existing noEmit bundler tsconfig permits .ts imports)
- make vendor.sh emit .ts in explicit rewrite rules and normalize both
  source styles across verbatim-copied generated modules
- guard hand-written and generated sources against either inexact form

Extension module import: 43.5ms -> 15ms median (PI_TIMING, n=12
interleaved). bun test: 73/73 (pi-extension), 456/456 (server); all
seven TypeScript project checks and the packed-artifact audit pass.

Co-authored-by: dca123 <dca123@users.noreply.github.com>
Co-authored-by: Michael Ramos <mdramos8@gmail.com>
2026-07-22 16:36:17 -07:00

86 lines
2.0 KiB
TypeScript

/**
* Editor annotation handler (in-memory store for VS Code integration).
* EditorAnnotation type, createEditorAnnotationHandler
*/
import { randomUUID } from "node:crypto";
import type { IncomingMessage } from "node:http";
import { json, parseBody } from "./helpers.ts";
interface EditorAnnotation {
id: string;
filePath: string;
selectedText: string;
lineStart: number;
lineEnd: number;
comment?: string;
createdAt: number;
}
export function createEditorAnnotationHandler() {
const annotations: EditorAnnotation[] = [];
return {
async handle(
req: IncomingMessage,
res: import("node:http").ServerResponse,
url: URL,
): Promise<boolean> {
if (url.pathname === "/api/editor-annotations" && req.method === "GET") {
json(res, { annotations });
return true;
}
if (url.pathname === "/api/editor-annotation" && req.method === "POST") {
try {
const body = await parseBody(req);
if (
!body.filePath ||
!body.selectedText ||
!body.lineStart ||
!body.lineEnd
) {
json(res, { error: "Missing required fields" }, 400);
return true;
}
const annotation: EditorAnnotation = {
id: randomUUID(),
filePath: String(body.filePath),
selectedText: String(body.selectedText),
lineStart: Number(body.lineStart),
lineEnd: Number(body.lineEnd),
comment: typeof body.comment === "string" ? body.comment : undefined,
createdAt: Date.now(),
};
annotations.push(annotation);
json(res, { id: annotation.id });
} catch {
json(res, { error: "Invalid JSON" }, 400);
}
return true;
}
if (
url.pathname === "/api/editor-annotation" &&
req.method === "DELETE"
) {
const id = url.searchParams.get("id");
if (!id) {
json(res, { error: "Missing id parameter" }, 400);
return true;
}
const idx = annotations.findIndex((annotation) => annotation.id === id);
if (idx !== -1) {
annotations.splice(idx, 1);
}
json(res, { ok: true });
return true;
}
return false;
},
};
}